Skip to content

Align Session input conflicts and tool result target errors - #74

Merged
SaladDay merged 4 commits into
mainfrom
codex/conflict-errors
Sep 23, 2026
Merged

SaladDay merged 4 commits into
mainfrom
codex/conflict-errors

Conversation

@SaladDay

@SaladDay SaladDay commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Every official 409 we observed uses type conflict_error, code conflict_error. Official tool_result admission rejects an unknown call or Turn inside an owned Session with 400 invalid_request_error. This batch aligns Core's public input conflicts and tool_result target errors with that. Documented Core-only conflict codes keep their codes, because the Core API may be a superset. The pinned baseline is unchanged (SDK 3.13.0 / d7c41ef / agents=v1).

Behavior

  • Every 409: type conflict_error.
  • Session input conflicts on events.create: 409 with code conflict_error. This covers a tool_result after cancellation, input while an input reservation is pending, and a changed result for a completed call.
  • Core extensions keep their codes; only the 409 type changes:
    • Session creation Idempotency-Key reuse (idempotency_conflict);
    • events request idempotency;
    • sandbox node administration;
    • environment_input_* states;
    • Environment file writes during work.
  • tool_result target errors, checked after the tenant-scoped Session lock:
    • an unknown call_id returns 400 invalid_request_error, "Unknown pending tool call.";
    • a real call with another or malformed turn_id returns 400 "The tool call belongs to a different Turn.";
    • the pending action is unchanged;
    • missing and foreign Sessions still get the same 404;
    • messages never repeat caller input or internal IDs.
  • Unchanged:
    • identical duplicate results (202);
    • admission timing (the official asynchronous pending window is an architectural difference);
    • Session-level isolation.
  • TS client: doc guidance for spanning old and new Cores. No production code branched on the old codes.

Evidence

Campaign scan 4 (ERR-22, ERR-27) and scan 2 (EVT-11, EVT-12), all with owned official resources that were deleted. Recorded in official-semantics-alignment.md, execution-tools.md and operation-evidence.md (register CF, row 11).

Validation

  • Live acceptance through real Core, the daemon, native Codex and Kimi K3, with a declared function tool (2 Turns per phase):

    Row main candidate
    Unknown call_id 404 400 invalid_request_error, pending action unchanged
    Other or malformed turn_id 404 / 400 invalid_request 400 invalid_request_error
    Changed result after completion 409 idempotency_conflict, type invalid_request_error 409 conflict_error/conflict_error
    Result after cancel 409 turn_conflict 409 conflict_error/conflict_error
    Creation key reuse 409, type invalid_request_error 409 type conflict_error, code idempotency_conflict
    Tenant B, identical duplicate 404, 202 unchanged

    The repository's official_pending_actions_native.py also passed all three rounds (success, error, cancel) on the hosted Runtime with Codex and Kimi K3 (3 Turns). Cleanup and secret scans passed.

  • Real-PostgreSQL test: exact bodies, no-write digests, unchanged Session reads, tenant B, a rolled-back mixed batch. Also API tests pinning every 409 body and the pinned-SDK official-client scripts.

  • Server gate on this head: all make check targets plus Web typecheck, core-doctor, unit tests and build pass. The Playwright browser cases were not run on the server (no Google Chrome; the user approved the skip). make openapi and make sqlc-generate are byte-identical.

  • Independent blind review by a fresh Claude Code subagent (the user-approved replacement for GPT-6 Astra): no blockers and no isolation leaks. Its three documentation nits are fixed in the last commit.

No full protocol compatibility is claimed.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

Every 409 now has type conflict_error, as every observed official conflict
does (ERR-27). On events.create, input the Session cannot accept (a result
after cancellation, a batch while earlier input is pending) and a changed
tool result use code conflict_error (EVT-12, ERR-22). Idempotency-Key reuse
and other Core-only conflicts keep their local codes.

Tool result targets are resolved after the tenant Session lookup: an unknown
call or a call of another, unknown or malformed Turn is 400
invalid_request_error with a fixed message and no writes (EVT-11), while
missing and foreign Sessions keep one 404.
The client and Core Web never branched on turn_conflict or
idempotency_conflict. Clarify that isSessionDeletionConflict applies only to
deleteSession, since input conflicts now share its code, and cover the new
fields alongside the codes of earlier Cores.
Add rows CF1-CF9 to the official semantics alignment, register CF in the
operation evidence with an updated events.create row, and update the
execution tools matrix, the EVT-11/12 deferral note and the contributor
error-mapping rules.
@SaladDay
SaladDay merged commit 1eb60c2 into main Sep 23, 2026
1 check passed
@SaladDay
SaladDay deleted the codex/conflict-errors branch October 7, 2026 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant