Skip to content

fix(config): accept a single mapping for hook event lists#3546

Merged
dgageot merged 1 commit into
mainfrom
fix/user-hooks-single-mapping
Jul 9, 2026
Merged

fix(config): accept a single mapping for hook event lists#3546
dgageot merged 1 commit into
mainfrom
fix/user-hooks-single-mapping

Conversation

@Sayt-0

@Sayt-0 Sayt-0 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Follow-up on the last comment of #3536: after the startup panic fix, the reported alias still did not load and runs fell back to the built-in default agent.

Fixes #3536

Root cause

settings.hooks events written as a single mapping instead of the documented list failed the whole config.yaml parse, so aliases and settings were silently dropped:

settings:
  hooks:
    on_user_input:        # mapping where a sequence was expected
      type: command
      command: terminal-notifier ...

Failure chain:

config.yaml parse error ("mapping was used where sequence is expected")
  -> userconfig.Load() returns an error
     -> resolve() skips alias resolution  -> built-in default agent used
     -> Get() returns empty Settings      -> original nil RestoreTabs panic

The startup panic fixed in 1a5ebd8 was a symptom of the same parse failure; this closes the remaining regression.

Change

item detail
HookDefinitions, HookMatcherConfigs new slice types for all hook event fields; unmarshal from a sequence or a single mapping (YAML and JSON)
precedent mirrors the instruction_file scalar-or-list pattern in pkg/config/latest/types.go
marshalling always emits a list, the canonical documented form
docs single-mapping form documented in the hooks page

Validation

check result
unit tests (hooks_flexible_test.go) list form, mapping form, scalar rejected, JSON parity, marshal normalizes to list
regression (TestConfig_SingleMappingHooksKeepAliases) the issue's exact config loads; alias, theme and hooks preserved
drop-ins (TestReadHookDropIn_SingleMapping) mapping form accepted; strict parsing still rejects typo'd fields
end-to-end binary alias list shows the alias, run default resolves it, doctor reports the config as ok
go test ./..., task lint pass; remaining failures are pre-existing network-dependent tests, also failing on main

Verification on the reporter's side is welcome: any other malformed section in the real config file would surface the same way and is out of scope here.

A hand-written user config with settings.hooks entries in mapping form
(stop: {type: command, ...}) instead of the documented list form failed
the whole config.yaml parse. Aliases and settings were then silently
dropped, so docker agent run <alias> fell back to the built-in default
agent, and before the GetRestoreTabs hardening the same parse failure
crashed the TUI at startup.

Hook event fields now use HookDefinitions and HookMatcherConfigs, slice
types that unmarshal from either a sequence or a single mapping (YAML
and JSON), mirroring the instruction_file scalar-or-list precedent.
They always marshal back as lists, the canonical documented form.

Fixes #3536
@Sayt-0
Sayt-0 requested a review from a team as a code owner July 9, 2026 08:39
@aheritier aheritier added area/config For configuration parsing, YAML, environment variables area/docs Documentation changes kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Jul 9, 2026
@dgageot
dgageot merged commit 11cf1d1 into main Jul 9, 2026
18 checks passed
@dgageot
dgageot deleted the fix/user-hooks-single-mapping branch July 9, 2026 09:46
Piyush0049 pushed a commit to Piyush0049/docker-agent that referenced this pull request Jul 15, 2026
fix(config): accept a single mapping for hook event lists
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config For configuration parsing, YAML, environment variables area/docs Documentation changes kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

panic: runtime error

3 participants