Bug
Workers (developers, reviewers, testers) frequently get stuck unable to call work_finish because the tool schema requires channelId but role prompts and agents often pass projectSlug instead.
Root cause
The work_finish tool schema marks channelId as required:
required: ["channelId", "role", "result"]
And resolveChannelId throws if it's missing:
if (!explicitChannelId) throw new Error("channelId is required...")
However, the task message injected by buildTaskMessage includes both:
Project: godot-game | Channel: C0ANYEYFCJ3
LLMs commonly read "Project: godot-game" and call work_finish({ projectSlug: "godot-game", ... }) instead of using the channelId — particularly in longer sessions where the task message is far back in context. The tool receives channelId: undefined and throws, leaving the worker stuck in a loop trying to find an alternative way to call the tool.
Impact
- Workers do their job (write code, review PR) but can't advance the pipeline
- Issues stay stuck on "Doing" / "Reviewing" / "Testing" indefinitely
- Heartbeat eventually zombie-kills and respawns, wasting tokens
Proposed fix
- Accept
projectSlug as an alias in work_finish execute:
const channelId = resolveChannelId(toolCtx, params.channelId || params.projectSlug);
-
Add projectSlug to the tool's JSON schema properties so the LLM knows it's valid
-
Make channelId optional in required (or add projectSlug as an alternative required field)
-
Default role prompt templates (devclaw/prompts/reviewer.md etc.) use projectSlug in their work_finish examples — these should be updated to use channelId to match the actual parameter name, or accept both.
Workaround
Patching ~/.openclaw/extensions/devclaw/dist/index.js locally to accept params.channelId || params.projectSlug and updating the role prompt templates.
Bug
Workers (developers, reviewers, testers) frequently get stuck unable to call
work_finishbecause the tool schema requireschannelIdbut role prompts and agents often passprojectSluginstead.Root cause
The
work_finishtool schema markschannelIdas required:And
resolveChannelIdthrows if it's missing:However, the task message injected by
buildTaskMessageincludes both:LLMs commonly read "Project: godot-game" and call
work_finish({ projectSlug: "godot-game", ... })instead of using the channelId — particularly in longer sessions where the task message is far back in context. The tool receiveschannelId: undefinedand throws, leaving the worker stuck in a loop trying to find an alternative way to call the tool.Impact
Proposed fix
projectSlugas an alias inwork_finishexecute:Add
projectSlugto the tool's JSON schema properties so the LLM knows it's validMake
channelIdoptional inrequired(or addprojectSlugas an alternative required field)Default role prompt templates (
devclaw/prompts/reviewer.mdetc.) useprojectSlugin theirwork_finishexamples — these should be updated to usechannelIdto match the actual parameter name, or accept both.Workaround
Patching
~/.openclaw/extensions/devclaw/dist/index.jslocally to acceptparams.channelId || params.projectSlugand updating the role prompt templates.