# Разбор TOML: незнакомый ключ и незнакомая секция не отказ, а тишина Отвечает на вопрос, возникший по ходу задачи `config-test-headers-login`: что делает декодер настроек с ключом и секцией, которых структура не знает, и виден ли этот случай хоть чем-нибудь. Наблюдение понадобилось потому, что ревью нашло опечатку в имени новой секции `[auth.test_headers]`, проходящую молча, и без разреза нельзя было сказать, где кончается предмет задачи и начинается свойство самой библиотеки. Соседняя записка о той же библиотеке — [toml-decode-errors.md](toml-decode-errors.md) — разбирает семейства **отказов**; здесь предмет обратный: случай, отказа не дающий. ## Как снималось Прогонами на зависимости, зафиксированной в `go.mod`: `github.com/BurntSushi/toml` версии **v1.5.0**. Оба уровня снял триаж ревью 2026-08-23, отчёт — [triage-2026-08-23.md](../../openspec/changes/archive/2026-08-23-config-test-headers-login/review/triage-2026-08-23.md), находка 2 и факт, подтверждённый разбором прохода `operations`. Временные файлы прогонов удалены, бинарник поднимался в каталог вне репозитория, не в `data/`. - **Модульный.** Вход `[server]\ndebug = true\n[auth]\n[auth.test_headrs]\n"Remote-User" = "dev"` — опечатка в имени секции. - **Сквозной.** Настоящий бинарник на конфиге с той же опечаткой, порт 18099, каталог данных вне репозитория; проба `curl /app/me`. ## Что выяснилось - **Незнакомая секция и незнакомый ключ отказа не дают: `decode err=`.** Разбор проходит целиком, поля структуры остаются нулевыми, и отличить «в файле этого нет» от «в файле это написано с опечаткой» по результату разбора нельзя. В прогоне: `Server.Debug=true len(TestHeaders)=0`. - **Потерянное называет только `MetaData.Undecoded()`.** Он возвращает перечень путей, которых структура не знала: `[auth.test_headrs auth.test_headrs.Remote-User]`. Значение это в проекте не читает никто — ни загрузка настроек, ни проверки старта. - **Контроль показывает, что дело в уровне, а не в разборе вообще.** Ту же опечатку **внутри** известной секции (`Remote-Usr` вместо `Remote-User`) ловит проверка старта — `auth: секция [auth.test_headers] называет заголовок, которого сервис не читает: Remote-Usr`, — потому что судит её код проекта, а не библиотека. Ошибка в имени самой секции до этого кода не доходит. - **Сквозной прогон следа не оставляет вовсе.** Бинарник поднимается без предупреждения, `curl /app/me` отвечает `401`, а в журнале стоит только `INFO "Incoming request" … http.status_code=401`. - **Отсюда направление отката бинарника безопасно.** Прежний образ, получивший конфиг с ключами, которых его структура ещё не знает, эти ключи игнорирует и поднимается. Свойство держится ровно на тишине выше: перечень `MetaData.Undecoded()` никто не судит. ## Что из этого следует для кода Свойство сегодня используется, а не терпится: правило выкладки «конфиг после образа» опирается именно на него, и его дом — [../architecture.md](../architecture.md), «Эксплуатация». Здесь записано, чем свойство обеспечено и как проверено, а не надо ли его менять. Отсюда же цена любой будущей проверки `MetaData.Undecoded()`: непонятый ключ, роняющий старт, закрывает опечатки во всех секциях разом — и тем же движением снимает безопасность отката, потому что прежний образ перестанет поднимать конфиг новее себя. Разменивать одно на другое — отдельное решение владельца, а не попутная правка. **Наблюдение привязано к версии.** Версия, начавшая судить незнакомые ключи сама, сменит оба следствия разом — молчаливую опечатку и безопасный откат.