Skip to content

subagent_ended hook does not fire for runs created via api.runtime.subagent.run() #59164

Description

@Amyssjj

Summary

api.on("subagent_ended", handler) never fires for subagent sessions created via api.runtime.subagent.run(). The hook only fires for runs created through the internal sessions_spawn tool path.

Root Cause

Two execution paths diverge:

sessions_spawn (tool) api.runtime.subagent.run() (plugin SDK)
Calls registerSubagentRun() Yes (sessions-spawn-tool.ts:259) No
Creates SubagentRunRecord Yes No
Tracked in subagent registry Yes No
Emits subagent_ended hook Yes (via subagent-registry-lifecycle.ts:148) No

When a plugin calls api.runtime.subagent.run(params):

  1. server-plugins.ts:328 dispatches to the gateway "agent" method
  2. server-methods/agent.ts:264 calls agentCommandFromIngress() directly
  3. No call to registerSubagentRun() — the run is never tracked in the subagent registry
  4. When the agent finishes, no SubagentRunRecord exists, so emitSubagentEndedHookOnce() is never called
  5. The plugin's api.on("subagent_ended", handler) never fires

Impact

Any plugin that uses api.runtime.subagent.run() to spawn workers and api.on("subagent_ended") to handle completion will never receive the completion event. These two APIs are documented as companion features but are not wired together.

Workaround

Workers can self-report completion by calling a plugin-registered tool (e.g. tasks.handoff) before their run ends. The plugin handles completion in the tool's execute handler instead of the hook.

Suggested Fix

The gateway's "agent" handler (server-methods/agent.ts) should call registerSubagentRun() for runs dispatched via the plugin SDK, so they participate in the normal subagent completion lifecycle and emit subagent_ended when done.

Reproduction

  1. Create a plugin that registers a tool and a subagent_ended hook
  2. Call api.runtime.subagent.run({ sessionKey: "test:key", message: "hello" })
  3. Wait for the run to complete
  4. Observe: the subagent_ended handler is never called

Environment

  • OpenClaw version: latest (as of 2026-03-31)
  • Affected files: src/gateway/server-plugins.ts, src/gateway/server-methods/agent.ts, src/agents/subagent-registry.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions