What happened, and what did you expect?
oh-my-opencode-slim exposes short Background Job Board aliases for specialist-session reuse. The orchestrator prompt (src/agents/orchestrator.ts) instructs:
"When reusing a specialist session, you MUST pass the existing session or alias in the task tool's task_id argument. If the Background Job Board lists fix-1 / ses_abc / fixer, call task with subagent_type: "fixer" and task_id: "fix-1" or task_id: "ses_abc"."
The task-session manager's handleToolExecuteBefore() (src/hooks/task-session-manager/tool-execute-hooks.ts) is expected to sanitize task_id before native execution: resolve reusable/recoverable aliases to the real ses_... id, delete unknown non-session values, or fail closed for running tasks.
What happened: On OpenCode 1.18.18 + plugin 2.2.14, a known non-ses_ Job Board value reached OpenCode's native SessionID.make() unchanged, even though Slim's tool.execute.before handler was invoked:
Expected a string starting with "ses", got "ora-1"
No child session was created.
Expected:
- A reusable alias is rewritten to its real
ses_... session ID.
- A known but non-reusable alias is removed or rejected before native execution.
- An unknown non-session value is removed or rejected before native execution.
Actual:
The native task tool received the original non-ses_ value and synchronously failed in SessionID.make(). In practice the model typically recovers on the next turn by retrying with the full ses_... id from the same Job Board entry, so the net impact is a wasted failed call plus an extra round-trip rather than a hard block — but the failed call is still avoidable and the alias guidance in the prompt remains misleading until fixed.
Steps to reproduce
-
An orchestrator session (ses_ff2faaa54ffeXxLV33ZvaSxRB2) launched an oracle foreground task. The plugin registered it on the board:
00:01:04.007 [task-session-manager] tentative early board registration from session.created
{"taskID":"ses_ff2fa6e06ffe4srJHhVXGpCKlq","alias":"ora-1","parentSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agent":"oracle"}
00:01:08.635 [task-session-manager] foreground task status registered
{"taskID":"ses_ff2fa6e06ffe4srJHhVXGpCKlq","alias":"ora-1","parentSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agent":"oracle","state":"completed"}
The task had completed but was not yet reconciled at this point.
-
~19 minutes later, resume with the alias as the prompt instructs:
{
"subagent_type": "oracle",
"task_id": "ora-1",
"description": "Analyze variant priority issue",
"prompt": "..."
}
-
The before-hook did run for this call (plugin log oh-my-opencode-slim.20260816T235734.log):
00:20:12.877 [task-session-manager] tool.execute.before task — pending call created
{"callId":"call_4c791c298214471680422aea","parentSessionId":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agentType":"oracle","label":"Analyze variant priority issue","inputCallID":"call_4c791c298214471680422aea","inputSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2"}
The pending-call log does not currently include resumedTaskId or the final task arguments, so its absence cannot prove which task-ID branch was selected. The native error is the authoritative evidence that the value eventually seen by OpenCode was still ora-1.
-
The native tool call failed:
Expected a string starting with "ses", got "ora-1"
-
Control — 32 seconds later, passing the full ses_ id from the same board entry succeeded:
00:20:44.325 [task-session-manager] tool.execute.before task — pending call created
{"callId":"call_2acbb0d4f6b54373a05e9d4e",...,"agentType":"oracle","label":"Analyze variant priority issue",...}
The session resumed successfully. This control confirms that the target session was resumable and that the native task tool succeeds when given the canonical session ID. It does not by itself identify whether the alias-resolution branch or the deletion branch failed.
Analysis:
At the time of the failing call (00:20:12), the task had completed but had not yet been reconciled — that transition happened at 00:35:18, 15 minutes after the failed call. In Slim's current implementation, resolveReusable() requires a completed terminal record with terminalUnreconciled === false and a context size within the configured limit. Therefore this reproduction primarily tests whether a known but non-reusable alias is safely removed or rejected before native execution. A separate post-reconciliation alias-resume test is needed to confirm a reusable-alias resolution failure.
In handleToolExecuteBefore(), every branch that handles a non-empty task_id either rewrites args.task_id, deletes it, keeps it only when it matches SESSION_ID_PATTERN (/^ses_[A-Za-z0-9_-]+$/), or throws for running tasks. None leaves "ora-1" in args.task_id.
OpenCode 1.18.18's v1 execution path passes the same args object through tool.execute.before and then to the native tool executor. Therefore, if handleToolExecuteBefore() actually deleted or rewrote args.task_id, the native executor should not see the original alias.
The observed behavior is inconsistent with that expected flow and strongly suggests that the mutation did not affect the arguments used by native execution. However, the current pending-call log does not prove that the delete/rewrite branch was executed. Additional branch-level and argument before/after logging is needed to distinguish these possibilities:
- the handler selected the wrong board branch;
- the argument was mutated but later restored;
- the host passed a different argument object to native execution;
- another hook restored the original value.
Suggested fix:
- Add branch-level logging (requested task_id, args before/after, branch selected, resolved task ID, board state,
terminalUnreconciled) to confirm whether the host propagates args mutations.
- Stop relying on silent deletion; throw with a recoverable message before native execution when
task_id is a non-ses_ value that cannot be safely transformed. Include the canonical ID only when the board has actually resolved the value.
- Prompt mitigation (temporary): require
task_id to be the full ses_... id; update the example accordingly.
- Regression test matrix at the native execution boundary — invariant: a non-
ses_ value must never reach SessionID.make().
Upstream context: anomalyco/opencode#37440 (same native failure mode), #37438 (open fix PR — would prevent the error but silently create a fresh session instead of resuming), #29964 (ses prefix constraint is long-standing).
Related history: #390 (introduced resumable aliases), #876 (hardened active-task reuse), commit 61a6603c (retained alias guidance).
oh-my-opencode.json
OpenCode version
1.18.18
oh-my-opencode-slim version
2.2.14
Operating system
macOS
Logs, screenshots, or extra context
# Plugin log: oh-my-opencode-slim.20260816T235734.log
# (v1 instance, directory=/Users/ybw0014/.config/opencode)
# 9 "pending call created" entries, matching the 9 task calls in this conversation.
00:01:04.007 [task-session-manager] tentative early board registration from session.created
{"taskID":"ses_ff2fa6e06ffe4srJHhVXGpCKlq","alias":"ora-1","parentSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agent":"oracle"}
00:01:08.635 [task-session-manager] foreground task status registered
{"taskID":"ses_ff2fa6e06ffe4srJHhVXGpCKlq","alias":"ora-1","parentSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agent":"oracle","state":"completed"}
00:20:12.877 [task-session-manager] tool.execute.before task — pending call created
{"callId":"call_4c791c298214471680422aea","parentSessionId":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agentType":"oracle","label":"Analyze variant priority issue","inputCallID":"call_4c791c298214471680422aea","inputSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2"}
# ← failing call (task_id="ora-1"), no resumedTaskId in log
00:20:44.325 [task-session-manager] tool.execute.before task — pending call created
{"callId":"call_2acbb0d4f6b54373a05e9d4e",...,"agentType":"oracle","label":"Analyze variant priority issue",...}
# ← control call (task_id="ses_ff2fa6e06ffe4srJHhVXGpCKlq"), succeeded
00:35:18.808 [task-session-manager] foreground task status registered
{"taskID":"ses_ff2fa6e06ffe4srJHhVXGpCKlq","alias":"ora-1","parentSessionID":"ses_ff2faaa54ffeXxLV33ZvaSxRB2","agent":"oracle","state":"reconciled"}
# ← reconciled transition, 15 min after the failed call
# Native error (returned as task_error to the orchestrator):
Expected a string starting with "ses", got "ora-1"
What happened, and what did you expect?
oh-my-opencode-slim exposes short Background Job Board aliases for specialist-session reuse. The orchestrator prompt (
src/agents/orchestrator.ts) instructs:The task-session manager's
handleToolExecuteBefore()(src/hooks/task-session-manager/tool-execute-hooks.ts) is expected to sanitizetask_idbefore native execution: resolve reusable/recoverable aliases to the realses_...id, delete unknown non-session values, or fail closed for running tasks.What happened: On OpenCode 1.18.18 + plugin 2.2.14, a known non-
ses_Job Board value reached OpenCode's nativeSessionID.make()unchanged, even though Slim'stool.execute.beforehandler was invoked:No child session was created.
Expected:
ses_...session ID.Actual:
The native task tool received the original non-
ses_value and synchronously failed inSessionID.make(). In practice the model typically recovers on the next turn by retrying with the fullses_...id from the same Job Board entry, so the net impact is a wasted failed call plus an extra round-trip rather than a hard block — but the failed call is still avoidable and the alias guidance in the prompt remains misleading until fixed.Steps to reproduce
An orchestrator session (
ses_ff2faaa54ffeXxLV33ZvaSxRB2) launched an oracle foreground task. The plugin registered it on the board:The task had completed but was not yet reconciled at this point.
~19 minutes later, resume with the alias as the prompt instructs:
{ "subagent_type": "oracle", "task_id": "ora-1", "description": "Analyze variant priority issue", "prompt": "..." }The before-hook did run for this call (plugin log
oh-my-opencode-slim.20260816T235734.log):The pending-call log does not currently include
resumedTaskIdor the final task arguments, so its absence cannot prove which task-ID branch was selected. The native error is the authoritative evidence that the value eventually seen by OpenCode was stillora-1.The native tool call failed:
Control — 32 seconds later, passing the full
ses_id from the same board entry succeeded:The session resumed successfully. This control confirms that the target session was resumable and that the native task tool succeeds when given the canonical session ID. It does not by itself identify whether the alias-resolution branch or the deletion branch failed.
Analysis:
At the time of the failing call (00:20:12), the task had completed but had not yet been reconciled — that transition happened at 00:35:18, 15 minutes after the failed call. In Slim's current implementation,
resolveReusable()requires a completed terminal record withterminalUnreconciled === falseand a context size within the configured limit. Therefore this reproduction primarily tests whether a known but non-reusable alias is safely removed or rejected before native execution. A separate post-reconciliation alias-resume test is needed to confirm a reusable-alias resolution failure.In
handleToolExecuteBefore(), every branch that handles a non-emptytask_ideither rewritesargs.task_id, deletes it, keeps it only when it matchesSESSION_ID_PATTERN(/^ses_[A-Za-z0-9_-]+$/), or throws for running tasks. None leaves"ora-1"inargs.task_id.OpenCode 1.18.18's v1 execution path passes the same
argsobject throughtool.execute.beforeand then to the native tool executor. Therefore, ifhandleToolExecuteBefore()actually deleted or rewroteargs.task_id, the native executor should not see the original alias.The observed behavior is inconsistent with that expected flow and strongly suggests that the mutation did not affect the arguments used by native execution. However, the current pending-call log does not prove that the delete/rewrite branch was executed. Additional branch-level and argument before/after logging is needed to distinguish these possibilities:
Suggested fix:
terminalUnreconciled) to confirm whether the host propagatesargsmutations.task_idis a non-ses_value that cannot be safely transformed. Include the canonical ID only when the board has actually resolved the value.task_idto be the fullses_...id; update the example accordingly.ses_value must never reachSessionID.make().Upstream context: anomalyco/opencode#37440 (same native failure mode), #37438 (open fix PR — would prevent the error but silently create a fresh session instead of resuming), #29964 (
sesprefix constraint is long-standing).Related history: #390 (introduced resumable aliases), #876 (hardened active-task reuse), commit
61a6603c(retained alias guidance).oh-my-opencode.json
OpenCode version
1.18.18
oh-my-opencode-slim version
2.2.14
Operating system
macOS
Logs, screenshots, or extra context