Skip to content

fix(agents): avoid empty Codex Responses input#74558

Merged
steipete merged 1 commit into
openclaw:mainfrom
vyctorbrzezowski:contrib/73820-openai-codex-empty-input
Apr 29, 2026
Merged

fix(agents): avoid empty Codex Responses input#74558
steipete merged 1 commit into
openclaw:mainfrom
vyctorbrzezowski:contrib/73820-openai-codex-empty-input

Conversation

@vyctorbrzezowski

Copy link
Copy Markdown
Contributor

Summary

  • Problem: openai-codex models using openai-codex-responses could build a request with input: [] when the context only had a systemPrompt.
  • Why it matters: ChatGPT's Codex backend rejects that shape with a 400 before the stream can complete.
  • What changed: Codex Responses payloads now keep system prompt text in top-level instructions and add a minimal sentinel user input item when there are no converted messages.
  • What did NOT change (scope boundary): Other OpenAI Responses providers, auth, model catalog, and tool conversion behavior are unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: Codex Responses moved the system prompt to top-level instructions, but still sent the converted message array as input; with no user/assistant/tool history, that array was empty.
  • Missing detection / guardrail: No focused test covered the openai-codex-responses system-prompt-only payload shape.
  • Contributing context (if known): The Codex backend requires one of input, previous_response_id, prompt, or conversation_id; an empty input array is treated as missing.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/openai-transport-stream.test.ts
  • Scenario the test should lock in: openai-codex-responses with systemPrompt and messages: [] produces non-empty sentinel input while preserving top-level instructions.
  • Why this is the smallest reliable guardrail: The bug is in buildOpenAIResponsesParams, so direct builder coverage catches the rejected payload shape without live Codex calls.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

OpenAI Codex provider turns that only have system-prompt-backed instructions no longer send input: [] to the ChatGPT Codex backend.

Diagram (if applicable)

Before:
systemPrompt only -> instructions set + input: [] -> backend 400

After:
systemPrompt only -> instructions set + one sentinel input_text item -> request is non-empty

Security Impact (required)

  • New permissions/capabilities? (Yes/No): No
  • Secrets/tokens handling changed? (Yes/No): No
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): No
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node v24.14.0, pnpm 10.33.0
  • Model/provider: openai-codex / openai-codex-responses
  • Integration/channel (if any): N/A
  • Relevant config (redacted): N/A

Steps

  1. Build OpenAI Responses params for an openai-codex model with API openai-codex-responses.
  2. Pass a context with systemPrompt set and messages: [].
  3. Inspect the request payload.

Expected

  • instructions contains the sanitized system prompt.
  • input is non-empty.

Actual

  • Before this fix, input was [].

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: focused unit coverage for system-prompt-only Codex Responses payloads; focused transport test suite; changed-file format; changed-lane gate.
  • Edge cases checked: system prompt cache boundary stripping is preserved in instructions; fallback input stays a small sentinel; non-Codex providers are not routed through the new fallback.
  • What you did not verify: no live ChatGPT/Codex backend call was made.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: The sentinel input adds a tiny user item to otherwise empty Codex requests.
    • Mitigation: The behavior is limited to openai-codex + openai-codex-responses and only when the converted input would otherwise be empty; the system prompt remains in instructions.

AI-Assisted Disclosure

  • AI-assisted: Yes
  • Testing degree: Focused local validation plus pnpm check:changed.
  • I confirm I reviewed the diff and understand the code change.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 29, 2026
@vyctorbrzezowski vyctorbrzezowski force-pushed the contrib/73820-openai-codex-empty-input branch from 5a2a67a to 85bcbe2 Compare April 29, 2026 19:05
@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes:

This PR adds a Codex Responses-only sentinel user input item for systemPrompt-only contexts, adds focused builder coverage, and records the fix in the changelog for #73820.

Maintainer follow-up before merge:

This is an open implementation PR that appears to address a valid provider bug; the remaining action is maintainer review, branch update if needed, and validation rather than a separate ClawSweeper repair PR.

Security review:

Security review cleared: The diff only changes same-endpoint Codex Responses payload shaping, a unit test, and a changelog entry; it does not alter dependencies, workflows, secrets, permissions, package scripts, or artifact execution.

Review details

Best possible solution:

Land a focused transport fix that keeps Codex system prompt text in top-level instructions, ensures systemPrompt-only openai-codex-responses requests carry a backend-accepted non-empty input item, leaves non-Codex Responses behavior unchanged, and keeps the regression test plus changelog credit.

Acceptance criteria:

  • pnpm test src/agents/openai-transport-stream.test.ts
  • pnpm check:changed in Testbox before landing, because this is an agent transport code change

What I checked:

  • Current main still permits empty Codex Responses input: buildOpenAIResponsesParams detects Codex Responses, converts messages with includeSystemPrompt: !isCodexResponses, then assigns input: messages; with an empty history and a system prompt, the system prompt is moved to instructions and the input array can remain empty. (src/agents/openai-transport-stream.ts:889, 97e2f5b3324b)
  • Message converter only adds system/developer content when requested: convertResponsesMessages starts with an empty ResponseInput array and only pushes the system/developer prompt when includeSystemPrompt is true; Codex Responses passes false, so empty context.messages leaves no input item. (src/agents/openai-transport-stream.ts:208, 97e2f5b3324b)
  • PR patch addresses the narrow failing shape: The PR adds ensureOpenAICodexResponsesInput(...) after conversion, scoped to openai-codex plus openai-codex-responses, and appends one input_text user item only when converted messages are empty and a system prompt exists. (src/agents/openai-transport-stream.ts:877, 5a2a67a9d46c)
  • PR includes focused regression coverage: The added unit test builds params for an openai-codex-responses model with systemPrompt and messages: [], then asserts top-level instructions are preserved and input contains the sentinel user item. (src/agents/openai-transport-stream.test.ts:1031, 5a2a67a9d46c)
  • OpenAI Responses contract check: The official Responses API reference documents input as the text/image/file input used to generate a response and instructions as a separate system/developer message, which supports preserving Codex instructions separately while making the input non-empty. citeturn1search0.
  • Related issue context supports the same bug: openai-codex provider sends empty input[] when context has only systemPrompt → ChatGPT 400 #73820 reports the ChatGPT Codex backend 400 when input: [] is sent, identifies active-memory's systemPrompt-only bootstrap as the trigger, and notes that switching away from openai-codex avoids the failure.

Likely related people:

  • steipete: Introduced the current Codex Responses top-level instructions handling in bc21f500... and has multiple recent OpenAI transport commits on the central source and test files. (role: introduced behavior and recent maintainer; confidence: high; commits: bc21f500d4c1, d1b2d81752b8, 05a93c178811; files: src/agents/openai-transport-stream.ts, src/agents/openai-transport-stream.test.ts)
  • methazoo: Recently changed the ChatGPT Codex backend base URL and documented live verification for the /backend-api/codex/responses route used by this provider path. (role: adjacent Codex route maintainer; confidence: medium; commits: 8a2d7f2541e0; files: extensions/openai/openai-codex-provider.runtime.ts, extensions/openai/openclaw.plugin.json, docs/providers/openai.md)
  • AytuncYildizli: Added openai-codex-responses to the model API schema after identifying that Codex OAuth tokens must route to the ChatGPT Codex Responses endpoint rather than standard OpenAI Responses. (role: introduced adjacent API schema support; confidence: medium; commits: 861b90f79c68; files: src/config/zod-schema.core.ts)

Remaining risk / open question:

  • The PR body says no live ChatGPT/Codex backend call was made, so maintainers may still want a live smoke proof before landing this backend-specific payload workaround.
  • The supplied GitHub context reports the PR as not mergeable, so the branch may need to be updated before normal merge validation.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 97e2f5b3324b.

@steipete steipete force-pushed the contrib/73820-openai-codex-empty-input branch from 85bcbe2 to 69314a6 Compare April 29, 2026 19:08
@steipete steipete merged commit 06b1d4e into openclaw:main Apr 29, 2026
65 of 66 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Landed in 06b1d4e. Thanks @vyctorbrzezowski.

I adjusted the fallback input to a single-space input_text sentinel before landing, matching the existing Gemini empty-content placeholder pattern without adding a semantic user instruction like Continue..

Verified:

  • pnpm test src/agents/openai-transport-stream.test.ts -- --reporter=verbose
  • pnpm exec oxfmt --check --threads=1 src/agents/openai-transport-stream.ts src/agents/openai-transport-stream.test.ts CHANGELOG.md
  • git diff --check
  • Public OpenAI Responses live shape check with instructions plus a single-space input_text succeeded; local Codex OAuth profile is expired, so I could not run the same request against the ChatGPT Codex backend here.

@vyctorbrzezowski vyctorbrzezowski deleted the contrib/73820-openai-codex-empty-input branch May 12, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openai-codex provider sends empty input[] when context has only systemPrompt → ChatGPT 400

2 participants