-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
Bug: binding to the implicit default agent "main" is rejected at config load and deleted by doctor --fix when agents.list is non-empty #89412
Copy link
Copy link
Open
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:crash-loopCrash, hang, restart loop, or process-level availability failure.Crash, hang, restart loop, or process-level availability failure.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:crash-loopCrash, hang, restart loop, or process-level availability failure.Crash, hang, restart loop, or process-level availability failure.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Summary
A route binding to the implicit default agent
"main"is treated as a dangling reference wheneveragents.listis non-empty. This breaks the documented ACP multi-agent shape (docs/tools/acp-agents.md: a few ACP agents inagents.list, with"main"routed for everything else) in two ways:loadConfigrejects the config withUnknown agent id "main" (not in agents.list)., so the gateway/CLI refuses to start after an upgrade.openclaw doctor --fixsilently deletes the bindings — the compatibility migration prunes every"main"binding from disk and reportsRemoved N bindings that referenced missing agents.list ids."main"(DEFAULT_AGENT_ID) is the implicit default agent everywhere else: routing binds anyagentIdand an unlisted agent simply runs onagents.defaults, andsession-key.tsuses"main"as the universal fallbackagentId. Only these two new code paths treat it as unknown.doctor(the very tool the load error tells the user to run, and which runs on update).mainagent viabindings(the documented ACP pattern).main@68833510Root cause
1. Load-time rejection —
src/config/zod-schema.ts:1280-1307. The bindingsuperRefinebuilds the allowed set fromagents.listonly and never addsDEFAULT_AGENT_ID:On
!ok,loadConfigLocal(src/config/io.ts) turns this into a throwncreateInvalidConfigError— a hard startup failure.2. Destructive doctor migration —
src/commands/doctor/shared/legacy-config-core-migrate.ts:12-43(pruneBindingsForMissingAgents, run from the exportednormalizeCompatibilityConfigValuesat line 72):Neither path adds
DEFAULT_AGENT_ID("main",src/routing/session-key.ts:26) to the allowed set. But binding to"main"is valid and functional:resolve-route.tschoose(matched.binding.agentId, ...)binds it as-is,resolveAgentConfig("main")returnsundefinedand the agent runs onagents.defaults, and"main"is the universal fallbackagentIdthroughoutsession-key.ts. The check was added alongside the onboarding-preservation work (the regression test is annotatedopenclaw#84692) and only ever considered the empty-agents.listcase, so the implicit-mainbinding ships unflagged.Reproduction
Standalone vitest against pristine
main(place at repo root asmainbind.test.ts):Observed (
main@68833510)Expected
The documented config loads without error, and
doctorpreserves the"main"route bindings."main"is the implicit default agent and is a valid binding target regardless ofagents.listcontents.Suggested direction
DEFAULT_AGENT_ID("main") as always valid in both predicates: add it toeffectiveAgentIdsin thesuperRefineand toagentIdsinpruneBindingsForMissingAgents, so only genuinely-dangling ids are rejected/pruned.docs/tools/acp-agents.mdconfig (load accepts it; prune leaves the"main"bindings intact).Happy to send a PR with the fix + the regression tests above.