permission denied while trying to connect to the Docker daemon socketpermission denied while trying to connect to the Docker daemon socket
Твій користувач не в групі docker. У Codespaces такого не буває; на своїй машині —
sudo usermod -aG docker $USER, а тоді вийди й зайди в систему знову (нова група
застосовується лише до нового сеансу).
📡 С.І.Д.: «Диспетчер тебе не знає. Це не відмова — це формальність: назвися й повертайся».
Cannot connect to the Docker daemon at unix:///var/run/docker.sockCannot connect to the Docker daemon at unix:///var/run/docker.sock
Демон не запущений. На Linux — sudo systemctl start docker; у Docker Desktop — запусти сам
застосунок і дочекайся зеленого індикатора.
📡 С.І.Д.: «Місто спить. Диспетчера нема на посту — будити нема кого».
bash: ps: command not foundbash: ps: command not found (усередині капсули)
Це не поломка, а нормальний стан: ubuntu:24.04 — мінімальний образ і ps у ньому немає.
Саме тому в етапі 2 ми спершу ставимо procps. Якщо пропусти[[g:в|ла]] цей крок — поверніся до нього.
📡 С.І.Д.: «У капсулі немає нічого зайвого. Хочеш дивитися на процеси — принеси інструмент».
docker: Error response from daemon: Conflict. The container name "/devbox-…" is already in usedocker: Error response from daemon: Conflict. The container name "/devbox-…" is already in use
Контейнер із таким іменем уже існує (найчастіше — з попередньої спроби). Прибери:
docker rm -f devbox-<суфікс>. Саме цю ситуацію на рівні 3 і треба зробити неможливою —
скрипт мусить бути ідемпотентним.
📡 С.І.Д.: «Одна брама, одне ім'я. Або прибирай стару капсулу, або назви нову інакше».
echo $$ показує не 1, а щось на кшталт 4213echo $$ показує не 1, а щось на кшталт 4213
Ти виконав команду не в капсулі, а на хості — термінал не той. Подивись на запрошення
рядка: усередині капсули воно на кшталт root@a1b2c3…:/#, а не твоє звичайне.
📡 С.І.Д.: «Ти питаєш місто, а не капсулу. Різні співрозмовники — різні відповіді».
Якщо помилка не з цього списку — шукай точний текст у «Коли щось пішло не так», там зібрані всі помилки курсу.
docker build падає з exec /sid: no such file or directorydocker build падає з exec /sid: no such file or directory — а файл же скопійований!
Класика scratch: бінарник динамічно злінкований і шукає /lib64/ld-linux-x86-64.so.2,
якого в порожньому образі немає. Збирай статично: Rust — --target x86_64-unknown-linux-musl
(спершу rustup target add), Go — CGO_ENABLED=0.
📡 С.І.Д.: «Ти взя[[g:в|ла]] мене в дорогу без ніг. Файл на місці, а спертися ні на що».
Кеш не спрацьовує: кожна збірка йде з нуля, хоча код не змінювався
Ти скопіюва[[g:в|ла]] весь каталог (COPY . .) до встановлення залежностей — і будь-яка
зміна в будь-якому файлі ламає кеш із цього місця й далі. Спершу копіюй тільки манифест
(Cargo.toml), потім став залежності, і лише потім — код.
📡 С.І.Д.: «Ти щоразу перебудовуєш майстерню, щоб забити один цвях».
Фінальний образ важить майже як наївний
Найчастіше — забутий AS build або COPY --from не з того етапу: тулчейн просто переїхав
у фінальний образ разом із результатом. Перевір docker history lab02-slim — важкі шари
видно одразу.
📡 С.І.Д.: «Ти зібра[[g:в|ла]] мене в новий костюм і взя[[g:в|ла]] з собою всю кравецьку».
Решта помилок курсу — у «Коли щось пішло не так».
curl: (6) Could not resolve host: storagecurl: (6) Could not resolve host: storage
Контейнери не в одній user-defined мережі. У стандартному bridge вбудованого DNS немає —
імена там не резолвяться взагалі. Перевір docker inspect agent | grep -i network і при
потребі під'єднай: docker network connect mission-net agent.
📡 С.І.Д.: «Листоноша не знає такої вулиці. Ти поклика[[g:в|ла]] його не в той квартал».
docker network create mission-net → network with name mission-net already existsdocker network create mission-net → network with name mission-net already exists
Мережа лишилася з попередньої спроби. Це нормально: docker network rm mission-net або
просто користуйся наявною.
📡 С.І.Д.: «Квартал уже змурований. Двічі мурувати не треба».
readlink /proc/<pid>/ns/net → Permission deniedreadlink /proc/<pid>/ns/net → Permission denied
Читання чужих просторів імен потребує прав: sudo readlink …. У Codespaces sudo доступний
без пароля.
📡 С.І.Д.: «Ти дивишся у вічко чужих дверей. Вартові просять показати перепустку».
docker inspectСекрет усе одно видно в docker inspect
Значення, передане через -e KEY=value, назавжди лишається в метаданих контейнера — його
видно і в docker inspect, і в історії команд оболонки. Саме тому рівень 3 вимагає файлу,
а не прапорця.
📡 С.І.Д.: «Ти написа[[g:в|ла]] ключ на конверті. Листоноша чесний, але конверт читають усі».
Решта помилок курсу — у «Коли щось пішло не так».
error[E0308]: mismatched typeserror[E0308]: mismatched types
Найчастіша помилка новачка: функція обіцяє String, а ти повертаєш &str (або навпаки).
Дивись на два рядки під помилкою: компілятор пише expected і found — саме в цьому порядку.
📡 С.І.Д.: «Ти обіця[[g:в|ла]] мені відмичку, а простягаєш креслення відмички. Різні речі».
error[E0425]: cannot find value ... in this scopeerror[E0425]: cannot find value ... in this scope
Опечатка в імені або змінна оголошена в іншому блоці. Rust не бачить нічого поза {},
у яких оголошено.
📡 С.І.Д.: «Такого інструмента на верстаку немає. Перевір, як ти його назва[[g:в|ла]]».
cargo: command not foundcargo: command not found
Тулчейн не встановлений або не в PATH. Постав: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh, тоді source "$HOME/.cargo/env". У devcontainer курсу Rust уже є —
перевір, що ти в контейнері, а не на хості.
📡 С.І.Д.: «Кузні немає. Ти прийш[[g:ов|ла]] кувати в порожній двір».
cargo test каже 0 tests, хоча тест написанийcargo test каже 0 tests, хоча тест написаний
Тест не в модулі з #[cfg(test)], або забутий атрибут #[test] над функцією, або файл не
той. Перевір обидва атрибути — вони обов'язкові.
📡 С.І.Д.: «Симулятор увімкнено, але випробовувати нічого. Ти не пода[[g:в|ла]] йому зразок».
warning: unused variable — і збірка все одно проходитьwarning: unused variable — і збірка все одно проходить
Це попередження, не помилка: Rust дозволяє зібратися, але каже, що щось зайве. Не ігноруй —
часто це і є слід справжньої помилки в логіці. Якщо змінна потрібна «про запас», назви її
_acc: підкреслення означає «знаю, що не використовую».
📡 С.І.Д.: «Компілятор не сварить — він показує пальцем. Подивись, куди».
Решта помилок курсу — у «Коли щось пішло не так».
error[E0382]: borrow of moved valueerror[E0382]: borrow of moved value
Це та помилка, яку ти сьогодні лагодиш, — але вона вилізе ще раз, якщо поставити & не там.
Дивись, куди вказує ^^^: це місце використання після переміщення, а не місце самого
переміщення. Причина завжди вище.
📡 С.І.Д.: «Ти [[g:віддав|віддала]] карту й тягнешся до неї знову. Її вже немає в руках».
error[E0308]: mismatched types — expected &str, found &Stringerror[E0308]: mismatched types — expected &str, found &String (або навпаки)
Класика першої правки: тип у сигнатурі змінили, а виклик ні (або навпаки). Найпростіше
тримати &str у параметрі й &log на виклику, як у Етапі 3, — тоді компілятор зведе
&String до &str сам.
📡 С.І.Д.: «Ми з тобою про одне й те саме, але різними словами. Домовмося про одні».
error[E0502]: cannot borrow ... as mutable because it is also borrowed as immutableerror[E0502]: cannot borrow ... as mutable because it is also borrowed as immutable
Ти тримаєш & на значення й одночасно намагаєшся змінити його. Правило одне: багато
читачів АБО один письменник. Найдешевше лікується звуженням області видимості —
загорни читання у { }, щоб позика скінчилася до запису.
📡 С.І.Д.: «Двоє тримають один аркуш, і один із них хоче його переписати. Спершу відпустіть».
error[E0499]: cannot borrow ... as mutable more than once at a timeerror[E0499]: cannot borrow ... as mutable more than once at a time
Два &mut на одне значення живуть одночасно. Той самий рецепт: скорочуй життя першої позики,
а не додавай .clone().
📡 С.І.Д.: «Два письменники, одне перо. Хтось мусить дописати перший».
cargo build зелений, а автогрейдер червонийcargo build зелений, а автогрейдер червоний
Майже завжди це .clone() замість запозичення або видалений другий log із format!.
Компілятор такий код пропускає — він справді компілюється. Але задача ночі була не «щоб
збиралося», а «щоб зрозуміти, хто чим володіє», і перевірка це розрізняє.
📡 С.І.Д.: «Ти обійш[[g:ов|ла]] Прикордонника, а не порозумі[[g:вся|лася]] з ним. Він пропустив — я ні».
Решта помилок курсу — у «Коли щось пішло не так».
error[E0004]: non-exhaustive patterns: ... not coverederror[E0004]: non-exhaustive patterns: ... not covered
У match не покритий якийсь варіант enum. Це не причепка, а вся суть прийому: компілятор
показує тобі стан, про який ти забу[[g:в|ла]]. Додай гілку — і не заклеюй дірку через
_ => ..., бо тоді наступний забутий варіант пройде молча.
📡 С.І.Д.: «Ти описа[[g:в|ла]] не всю варту. Один вартовий лишився без інструкції».
error[E0428]: the name 'GuardNode' is defined multiple timeserror[E0428]: the name 'GuardNode' is defined multiple times
Класика рівня 3: структуру оголосили вдруге, замість того щоб додати поле до наявної. Один
тип — одне оголошення.
📡 С.І.Д.: «Два креслення одного вузла. Яке з них справжнє?»
error[E0063]: missing field 'sensor' in initializer of 'GuardNode'error[E0063]: missing field 'sensor' in initializer of 'GuardNode'
Щойно з'явилося нове поле, кожен літерал GuardNode { ... } мусить його вказати. Це
добра новина: компілятор сам перелічив тобі всі місця, які треба оновити. Пройди списком і
допиши sensor: None.
📡 С.І.Д.: «Схема змінилася — а три вузли ще збудовані за старою».
error[E0308]: mismatched types — 'expected u8, found integer'error[E0308]: mismatched types — 'expected u8, found integer' (та подібні)
Alert(u8) тримає число до 255. Якщо підставляєш більше або інший числовий тип — компілятор
зупинить. Тип варіанта — це теж контракт, і він теж навмисний.
📡 С.І.Д.: «Рівень тривоги в них однобайтовий. Двобайтовий підпис нас видасть».
thread 'main' panicked at 'called Option::unwrap() on a None value'thread 'main' panicked at 'called Option::unwrap() on a None value'
Єдина помилка з цього списку, яку компілятор не зловить: unwrap() компілюється завжди й
падає в рантаймі. Саме тому в рівні 3 його немає — обидва рівні вкладеного Option
обробляються match-ем.
📡 С.І.Д.: «Ось вона, порожнеча. Аварійна зупинка просто в них під носом — і підпис чужинця в їхньому журналі».
Решта помилок курсу — у «Коли щось пішло не так».
error[E0308]: mismatched types — 'expected Result<String, ReadLogError>, found String'error[E0308]: mismatched types — 'expected Result<String, ReadLogError>, found String'
Забутий Ok(...) на успішній гілці. Функція обіцяла Result, а ти повертаєш саме значення.
📡 С.І.Д.: «Ти простягаєш мені дані без конверта. Я не бачу, успіх це чи ні».
warning: unused Result that must be usedwarning: unused Result that must be used
Виклик, що повертає Result, проігнорований. Це попередження, а не помилка, — і саме тому
небезпечне: код збереться, а провал зникне безслідно. Обробляй або свідомо пиши let _ = ....
📡 С.І.Д.: «Хтось повідомив про міну, а ти не прочита[[g:в|ла]] записки».
the ? operator can only be used in a function that returns Resultthe ? operator can only be used in a function that returns Result (E0277)
Класика рівня 2: ? поставили у функцію, яка повертає звичайне значення — найчастіше в
main або в цикл обробки списку. У циклі ? не потрібен принципово: він зупинив би
всю обробку через один битий файл.
📡 С.І.Д.: «Не тікай із поля через одну міну. Обійди її й іди далі».
test corrupted_file_returns_corrupted ... FAILED — а файл наче побитийtest corrupted_file_returns_corrupted ... FAILED — а файл наче побитий
Фікстура створена текстовим редактором, який «полагодив» невалідний байт при збереженні.
Роби її байтами: printf 'Hi\xff!' > fixtures/corrupted_log.bin — і перевір
xxd fixtures/corrupted_log.bin.
📡 С.І.Д.: «Твоя міна виявилася муляжем. Редактор її обеззброїв».
Тест прав доступу проходить там, де мав би провалитися
chmod 000 не діє на root, а в багатьох контейнерах процес запущений саме від root.
Перевір whoami; якщо root — це не твоя помилка, і варіант 2 таблиці просто не
відтворюється в цьому середовищі.
📡 С.І.Д.: «Замок є, але ти маєш ключ від усіх дверей. Перевір, хто ти в цій системі».
Решта помилок курсу — у «Коли щось пішло не так».
wat2wasm: error: unexpected token ")", expected ...wat2wasm: error: unexpected token ")", expected ...
Дужки. У .wat вони структурні, як у Lisp: кожен (func ...) мусить закритися, і
редактор тут головний друг — став курсор на дужку й дивись, куди підсвітилася пара.
📡 С.І.Д.: «Речення без крапки. Машина чекає, чим ти [[g:закінчив|закінчила]] думку».
type mismatch in implicit return, expected [i32] but got []type mismatch in implicit return, expected [i32] but got []
Функція обіцяла (result i32), а стек у кінці порожній: чи то забутий local.get, чи то
інструкція зняла більше, ніж ти [[g:поклав|поклала]]. Порахуй руками: скільки кладу,
скільки знімаю, що лишається.
📡 С.І.Д.: «Ти обіця[[g:в|ла]] машині число й простягаєш порожню руку».
RuntimeError: unreachable executedRuntimeError: unreachable executed
Заглушка unreachable лишилася в тілі функції. Це не збій — це навмисна пастка стартера:
доки її не прибра[[g:в|ла]], модуль компілюється, але падає при виклику.
📡 С.І.Д.: «Ти лиши[[g:в|ла]] в кресленні напис «тут нічого немає». Машина прочитала буквально».
TypeError: Failed to fetch / CORS request not httpTypeError: Failed to fetch / CORS request not http
Сторінку відкрито як file://, без сервера. Підніми python3 -m http.server 8080 і
зайди через http://localhost:8080/.
📡 С.І.Д.: «Ти стукаєш у двері, яких для браузера не існує. Дай йому адресу».
RuntimeError: memory access out of boundsRuntimeError: memory access out of bounds (рівень 3)
Звернення за межі виділеної сторінки. Це правильна робота пісочниці, а не поломка: одна
сторінка — 65 536 байтів, і адреса 70000 за нею. Саме цього не станеться в ЛР9, і саме
тому WASM пускають у браузер.
📡 С.І.Д.: «Стіна є, і вона тримає. Мені це, зізнаюся, подобається».
Решта помилок курсу — у «Коли щось пішло не так».
objdump: command not found / wasm-objdump: command not foundobjdump: command not found / wasm-objdump: command not found
Не встановлені binutils (перший) або WABT (другий). У devcontainer курсу обидва є —
перевір, що ти в контейнері, а не на хості.
📡 С.І.Д.: «Скальпеля немає. Розтин без інструмента — просто розглядання».
x86.txt майже порожній, у ньому лише кілька рядківx86.txt майже порожній, у ньому лише кілька рядків
Забуте -c: без нього gcc намагається зібрати повну програму, не знаходить main і
падає, а objdump читає стару або порожню .o. Перевір, що algo_x86.o щойно
створений (ls -la).
📡 С.І.Д.: «Ти [[g:приніс|принесла]] мені порожній стіл і кажеш, що тіла не було».
x86.txt немає ні push %rbp, ні окремої функціїУ x86.txt немає ні push %rbp, ні окремої функції
Збірка пішла з оптимізаціями — компілятор зробив inline і викинув пролог. Для цієї
роботи потрібне саме -O0.
📡 С.І.Д.: «Компілятор виявився надто послужливим і прибрав усе, що ми прийшли дивити».
wasm32 target not found / emcc: command not foundWASM-збірка падає: wasm32 target not found / emcc: command not found
Основний шлях — clang з таргетом wasm32 (шлях Б у build.sh): він дає самодостатній
модуль без імпортів, і саме такий очікує автотест. Emscripten (шлях А) підходить лише
з прапорцем -sSTANDALONE_WASM — без нього модуль вимагає середовища Emscripten і не
інстанціюється, тобто автотест упаде. Якщо clang без таргета wasm32 — не вигадуй обхід,
став пакет lld або бери шлях А саме зі STANDALONE_WASM і зазнач це в
comparison.md.
📡 С.І.Д.: «Дві дороги до того самого столу. Іди тією, що відчинена».
Порівняння вийшло «WASM менший, отже швидший»
Найчастіша змістова помилка ночі, а не технічна. Розмір файлу не є мірою швидкодії:
кодування WASM щільніше, а .o несе метадані ELF. Висновок «менший ≠ швидший» і є
правильною відповіддю.
📡 С.І.Д.: «Тонша книжка не означає швидше читання. Порівнюй те, що можна порівняти».
Решта помилок курсу — у «Коли щось пішло не так».
Error: rust-wasm-bindgen version mismatchError: rust-wasm-bindgen version mismatch (або
it looks like the Rust project used to create this wasm file had a different version)
Версія в Cargo.toml і версія CLI розійшлися. Або постав CLI тієї самої версії
(cargo install -f wasm-bindgen-cli --version 0.2.92), або лиши ="=0.2.92" у
Cargo.toml і не оновлюй. Це найчастіша поломка ночі.
📡 С.І.Д.: «Дві половини ядра з різних креслень не зійдуться. Я це знаю краще за всіх».
Сторінка відкривається, консоль порожня, нічого не працює
Зібрано не з --target web. Ціль bundler (типова) розрахована на webpack і в
браузері напряму не запуститься — причому без помилки. Перезбери з --target web.
📡 С.І.Д.: «Ти [[g:зібрав|зібрала]] мене для іншої машини. Тиша — це не відмова, це непорозуміння».
error: cannot produce cdyliberror: cannot produce cdylib / у pkg/ немає .wasm
Забутий [lib] crate-type = ["cdylib"] у Cargo.toml.
📡 С.І.Д.: «Кузня видала заготовку, а не ядро. Скажи їй, що саме кувати».
TypeError: Failed to fetch під час init()TypeError: Failed to fetch під час init()
Знову file:// замість сервера, або pkg/ лежить не там, куди дивиться
index.html. Перевір шлях в import init from './pkg/sid_core.js'.
📡 С.І.Д.: «Двері є, але не за тією адресою, яку ти [[g:назвав|назвала]]».
Два хеші зійшлися з першого разу, без чистого каталогу (рівень 3)
Це не успіх, а хибний результат: друга збірка взяла артефакт із шарів Docker або зі
старої pkg/. Прибери pkg/ і target/ між запусками — і збери ще раз.
📡 С.І.Д.: «Два відбитки одного пальця — доказ. Двічі показаний той самий відбиток — ні».
Решта помилок курсу — у «Коли щось пішло не так».