Repository navigation
[Bug] V2 custom-parent → custom-child delegation needs current-dev trace #418
Description
Area
V2 multi-agent delegation / routed providers
Current status
This issue originally reported that a custom-routed parent → custom-routed child V2 delegation failed on OpenCodex 2.7.39.
The original failure was:
failed to parse function arguments: missing field `message` at line 1 column 2
with no completed child result surfaced to the parent.
Subsequent testing has narrowed the problem, but has not yet reproduced the original custom-parent → custom-child failure on current dev.
The issue therefore remains open pending one current same-run trace across the relevant boundaries.
What has been established
The generic Responses bridge is not unconditionally dropping tool arguments
A 2.7.39 control capture showed ordinary structured tool calls arriving from a custom-routed provider with non-empty arguments and being emitted correctly through:
response.output_item.added
response.function_call_arguments.delta
response.function_call_arguments.done
response.output_item.done
That rules out a generic unconditional argument-loss bug in the OpenAI-compatible adapter / Responses bridge.
A later V2 delegation run completed, but on the wrong model
A later reproduction on OpenCodex 2.10.0 used:
- native parent:
gpt-5.6-luna - requested custom child:
google-antigravity/gemini-3.6-flash fork_turns: "none"- reasoning effort:
medium
The collaboration completed and returned the expected sentinel.
However, the parent-generated spawn_agent arguments omitted the model field:
{
"task_name": "custom_child_sentinel",
"fork_turns": "none",
"message": "<opaque payload>"
}The proxy therefore received no explicit child-model override and all requests remained on the inherited native route.
No request reached the requested custom provider.
This is a different failure from the original 2.7.39 custom-parent → custom-child report.
Current OpenCodex behavior
The current branch advertises valid V2 model overrides and its collaboration guidance tells the parent to honor a user-named model.
The relevant guidance is emitted from:
src/server/responses/collaboration.ts
The remaining question is whether a current custom-routed parent:
- emits a correct
modelfield when asked to use a specific custom child model; and - successfully creates and completes that routed child.
Needed reproduction
Run one test against current dev with:
- a custom-routed parent
- a different custom-routed child
- an explicitly named child model
fork_turns: "none"- a deterministic sentinel response
Capture all three boundaries from the same run.
Boundary 1 — provider output
Capture the provider-emitted spawn_agent call, including:
- tool name
- presence/value of
model - argument byte length or redacted arguments
- finish reason
Boundary 2 — OpenCodex translation
Capture the corresponding:
response.output_item.*
response.function_call_arguments.*
events and the route selected for the child.
Boundary 3 — Codex collaboration lifecycle
Capture whether Codex reports:
- child creation
- child completion
- child failure
- returned child result
How to interpret the result
Provider omits model
If the custom parent is explicitly told to use another model but emits no model field, the remaining defect is in the model guidance / collaboration prompt surface.
That is actionable in OpenCodex.
Provider emits the correct model, but the child does not route or complete
If the provider emits the requested model correctly and the OpenCodex bridge preserves it, but the child still fails to appear or complete, the failure is further downstream in the V2 collaboration lifecycle.
That boundary should then be investigated separately.
Relationship to #92
Related to, but not a duplicate of, #92.
#418
Custom-routed parent → custom-routed child.
Current question:
Does an explicitly requested custom child model survive spawn_agent and complete?
#92
Native parent → routed child with an upstream encrypted NEW_TASK payload.
The two issues share the V2 collaboration surface but have different failure boundaries and should remain separate.
Workaround
Until the current custom→custom path is conclusively traced:
- use V1 delegation; or
- inherit the parent model instead of explicitly routing the child to another custom model.
Acceptance / closure criteria
This issue can move out of needs-info when a current-dev custom-parent → custom-child run provides the three-boundary trace above.
It can be closed when either:
- current
devsuccessfully honors the explicit custom child model and completes the child, showing that the historical failure no longer reproduces; or - a deterministic current failure is isolated and fixed with regression coverage.
Checks
- Historical failure is preserved in the discussion.
- Generic tool-argument loss has been ruled out.
- V2 cross-provider sub-agent loses NEW_TASK body in encrypted_content #92 has been confirmed as related but distinct.
- The missing evidence is precisely defined.
- Current-
devcustom-parent → custom-child same-run trace captured.
Activity
Ingwannu commentedon Jul 24, 2026
Thanks for the follow-up. The earlier 2.7.33 four-boundary capture established that OpenCodex preserved the incoming/outgoing
spawn_agentschema and that the custom upstream returned a function call with a zero-byte argument string. That specific capture therefore pins the loss before the Responses event bridge rather than proving an OpenCodex argument-drop defect.The 2.7.39 report is still useful, but it no longer reproduces the empty-arguments signature and currently only establishes an end-to-end delegation failure. Please capture, from the same 2.7.39 run, (1) the raw provider tool-call name/arguments and finish reason, (2) emitted
response.output_item.*/response.function_call_arguments.*events, and (3) whether Codex emits any collaboration child-created/completed notification. A redacted trace is sufficient. We will keep this open while separating provider structured-tool emission from a Codex V2 collaboration lifecycle failure. The reliable workaround remains V1 or inheriting the parent model.brunoflma commentedon Jul 24, 2026
Thanks. I repeated the investigation on the same local 2.7.39 installation and separated the observations below. All provider-specific names, credentials, request headers, and private task content are omitted; the parent and child were custom-routed models.
Environment
2.7.390.145.024.16.026200multi_agent_v2: OFF,multi_agent_mode: v2medium.Original end-to-end custom-parent -> custom-child probe
The parent was a custom-routed model. It was instructed to create exactly one child with an explicit custom-routed model override,
reasoning_effort: "medium",fork_turns: "none", and a self-contained child task whose expected output was a fixed sentinel. The parent was instructed to wait and return only that child result.Observed client-side result from the 2.7.39 probe:
This occurred repeatedly during the parent turn. The corresponding local, sanitized usage records show successful custom-routed upstream HTTP responses during that interval. No child sentinel was returned and no successful child result was surfaced to the parent.
I did not see any Codex collaboration
child-createdorchild-completednotification in the CLI JSON output for that failing run. The CLI only showed the parent turn progressing/retrying and then the argument-validation failure above.Important limitation: the temporary raw-boundary instrumentation was installed after this particular failing run, so I cannot honestly claim a raw provider
spawn_agentargument record for that same run.2.7.39 transport control capture
I then instrumented the local 2.7.39 OpenAI-compatible adapter and Responses bridge briefly, with a local-only trace. It recorded only tool name, argument byte length, finish reason, and Responses event shape. The instrumentation was removed afterwards and the proxy was restarted cleanly.
For ordinary structured tool calls in the same running 2.7.39 proxy, the transport path was intact:
The actual tool arguments are deliberately not included because they contained local paths and unrelated operational commands. The byte lengths above are retained to make clear that they were non-empty. This control confirms that 2.7.39 can preserve non-empty structured-call arguments through this adapter and the Responses event bridge. It does not prove that
spawn_agenttakes the same path in the failing collaboration case.Attempts to obtain the matching
spawn_agenttracespawn_agent, reporting that the requested child model was not available on the collaboration surface. No provider tool call or lifecycle event was emitted in that attempt.fork_turns: "none"andreasoning_effort: "medium".spawn_agentcall was made. Therefore it produced no raw provider tool-call record, noresponse.output_item.*function-call events forspawn_agent, and no child-created/completed notification.I am including those failed capture attempts because they distinguish two separate issues:
missing field messageand no child completed; andspawn_agentcapture after the instrumentation was added.Current conclusion
The control trace rules out a general, unconditional argument loss in the 2.7.39 OpenAI-compatible adapter/Responses bridge: non-empty ordinary function-call arguments arrived from the custom-routed upstream and were emitted as non-empty
response.function_call_arguments.delta,.done, and completed output-item arguments.However, the custom-parent -> custom-child V2 path remains unresolved. The original 2.7.39 end-to-end probe still produced repeated client validation failures (
missing field message), no child result, and no observed collaboration child lifecycle notification. Because I could not obtain a new rawspawn_agentcall after the limit was reached, I cannot yet attribute the current failure to provider structured-tool emission versus Codex V2 collaboration lifecycle handling.When the client usage limit clears, I will repeat exactly this controlled one-child probe with instrumentation already prepared and provide the requested three boundary records from one run:
spawn_agentname, argument byte length/redacted arguments, and finish reason;response.output_item.*andresponse.function_call_arguments.*event for that call; andFor now, I agree with the workaround recommendation: use V1 or inherit the parent model for delegated work until this V2 custom-parent -> custom-child path can be conclusively traced and fixed.
Wibias commentedon Jul 26, 2026
Cross-link
Related to (but not the same as) #92.
spawn_agentargs / validation (missing field message; no child lifecycle)NEW_TASKas Fernetencrypted_contentSame V2 collaboration surface; different root causes. Do not close either as a duplicate of the other. #92 remains upstream-blocked; this issue stays open pending the three-boundary
spawn_agentcapture already requested.github-actions commentedon Jul 26, 2026
Automated translation bookkeeping — detected language: English.
docs(devlog): correct the decision ledger against an independent audit
lidge-jun commentedon Aug 2, 2026
Triage status: to assign this failure we need one same-run trace across the three boundaries — (1) what the custom provider actually emitted, (2) what the proxy translated/forwarded, (3) what the Codex lifecycle received at spawn_agent. A single repro run with those three captures lets us name the faulty layer instead of guessing.
brunoflma commentedon Aug 2, 2026
Here is the same-run trace across the three boundaries, on
2.10.0. I instrumented the proxy temporarily to tee (1) the body sent upstream and (2) the raw body the provider returned, keyed per turn; (3) comes from the Codex CLI run itself. The instrumentation was reverted afterwards.It does not fail the way the original report described any more — and I think the layer is now nameable. The run completes and returns the sentinel. What does not happen is the child ever reaching the requested custom provider: it silently inherits the parent's model.
Setup
2.10.0, Codex CLI0.146.0, Windows 11,multi_agent_mode: v2gpt-5.6-luna(native passthrough)google-antigravity/gemini-3.6-flash(custom-routed),reasoning effort medium,fork_turns noneCUSTOM-CHILD-SENTINEL OK, parent waits and returns it verbatim, explicitly told not to do the task itselfI could not use a custom-routed parent for this run: my
AGR-*provider currently returns401 unauthorized client detectedbefore any request reaches the proxy, so the parent had to be a native model. Boundary 3 is therefore native-parent → custom-child rather than custom → custom. Everything below is still about the child override, which is the part that fails.Boundary 3 — what the Codex lifecycle did
The tool ran, the collaboration surface entered
Wait, and the sentinel came back. From the client's point of view this is a success.Boundary 1 — what the parent actually emitted
Two
spawn_agent-family calls, fromresponse.function_call_arguments.done:{"task_name":"custom_child_sentinel","fork_turns":"none","message":"gAAAAAB…<248 chars, opaque>"} {"timeout_ms":3600000}There is no
modelfield. Reproduced identically across two runs. Themessageis an opaque Fernet-style blob rather than the plaintext task — worth noting given themissing field \message`` / zero-byte-argument history in #290, though nothing failed on it here.Boundary 2 — what the proxy forwarded
Four upstream calls, all of them:
No call to
google-antigravityat any point. The child ran on the parent's inherited route. Routing did exactly what it was told — it was never told anything else.The interesting part is why the parent omitted
model. Thespawn_agenttool description carries the injected roster, and it reads:So the requested model is advertised and correctly described as routed via opencodex — the roster injection works. But the same text tells the model that inheriting is preferred and to omit
model. Faced with a user instruction naming a specific child model and tool guidance saying the inherited default is preferred, the parent followed the guidance.Where that points
This looks like a guidance/prompt-surface issue rather than a routing one:
modelparameter: available, just steered away fromTwo things that might be worth deciding separately:
model" reads as a recommendation against overrides in general, not as a description of the default. Something like "omitmodelto inherit; set it whenever the task names a specific model" would leave the default intact while not discouraging an explicit request.I have the full per-turn captures (request bodies and raw upstream SSE). They contain conversation content and provider headers so I have not attached them, but I am happy to extract any specific frame you want, or to re-run with a different parent/child pair.
One caveat on the original report
My run does not reproduce "no child sentinel is returned". Either that part was fixed between
2.7.39and2.10.0, or it is specific to a custom-routed parent, which I cannot test until myAGR-*access is back. If you would like the custom→custom case specifically, say so and I will re-run once that clears.lidge-jun commentedon Aug 2, 2026
Triage: the branch now advertises valid V2 overrides and instructs the parent to honor a user-named model (src/server/responses/collaboration.ts:266), but coverage is guidance/catalog-level — no same-run custom-parent → custom-child live trace exists. Leaving open pending a live reproduction on the latest dev.
lidge-jun commentedon Aug 3, 2026
Re-triaged against current
dev. Not stale, and not a duplicate of #92 — but the newest trace attached here does not show the failure you originally reported, and that distinction matters for what to fix.The V2 delegation path still exists: model guidance is emitted at
src/server/responses/collaboration.ts:266-275, including the "use [preferred] unless the user names another" instruction. So the code is there to examine.The trace from 2.10.0 completed on the inherited native model because
modelwas omitted from the spawn arguments. That is a different failure from the custom-parent → custom-child pairing in the original report: one is guidance not producing a model argument, the other is a routed child never surfacing. They would need different fixes, and I cannot tell from here which one you are still hitting.What would settle it: one run on current
devwith a custom parent delegating to a custom child, showing the provider-emittedspawn_agentarguments, the proxy events, and the child's lifecycle. If the provider emits nomodelargument at all, this is guidance and I can fix it; if it emits one and the child still never surfaces, the problem is downstream and I will trace it from there.The 2.7.39 version in the title is old enough that I would not want to debug against it — a current trace is worth more than anything I can reconstruct from the original.
[-]V2 custom-parent to custom-child delegation still fails on 2.7.39[/-][+][Bug] V2 custom-parent → custom-child delegation needs current-dev trace[/+]Wibias commentedon Aug 11, 2026
The last response was 7 days ago. If you still encounter this problem @brunoflma feel free to open a new issue with the newest trace. Thank you.
Closing this.