Skip to content

fix(acpx): prevent duplicate -c config overrides for Codex ACP command#74339

Open
SymbolStar wants to merge 3 commits into
openclaw:mainfrom
SymbolStar:fix/acpx-codex-overrides-74305
Open

fix(acpx): prevent duplicate -c config overrides for Codex ACP command#74339
SymbolStar wants to merge 3 commits into
openclaw:mainfrom
SymbolStar:fix/acpx-codex-overrides-74305

Conversation

@SymbolStar

Copy link
Copy Markdown
Contributor

Root Cause

When a user configures the ACPX Codex command with -c model=gpt-5.5 -c model_reasoning_effort=medium, and the runtime model override scope is active (e.g. via sessions_spawn with model/thinking), appendCodexAcpConfigOverrides blindly appended additional -c args to the command string without checking if those keys were already present. This caused duplicate -c model=... / -c model_reasoning_effort=... args to be passed to the codex-acp adapter.

Additionally, on v2026.4.26 (the reported version), the older wrapper code and codex-acp 0.11.x dependency had different arg handling that contributed to the failure. Current main already improved the wrapper normalization and upgraded to codex-acp 0.12.0, but the duplicate-append issue remained.

Changes

  • extensions/acpx/src/runtime.ts: Add commandHasConfigKey() that checks if a command string already contains a -c <key>=... arg. Modified appendCodexAcpConfigOverrides() to skip appending a -c override if that config key is already present in the command string, preventing duplication.

  • extensions/acpx/src/runtime.test.ts: Added tests covering:

Fixes #74305

…and already has them

When a user configures the ACPX Codex command with -c model=X and/or
-c model_reasoning_effort=Y, and the runtime also passes model/thinking
overrides, appendCodexAcpConfigOverrides previously appended duplicate
-c args blindly. This could cause unexpected behavior with the adapter.

Now check if the command string already contains -c <key>=... before
appending, respecting configured values as the baseline. This prevents
doubling of -c args in the spawned codex-acp process.

Also adds tests covering:
- Configured command args not being duplicated (openclaw#74305 scenario)
- Partial overlap (only missing keys are appended)
- The wrapper command variant with pre-existing -c args

Fixes openclaw#74305
@greptile-apps

greptile-apps Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a commandHasConfigKey helper that inspects an already-split command string for a given -c flag, then uses it in appendCodexAcpConfigOverrides to skip appending an override whose key is already present. This prevents the duplicate-arg breakage when a user has both a pre-configured model flag and a runtime model scope active simultaneously.

Confidence Score: 4/5

Safe to merge; fixes a real crash with no regressions on the reviewed path.

No P0/P1 issues found. Two P2 style observations: (1) a silent precedence rule where a runtime model override is quietly dropped when the configured command already carries that key, and (2) a trivially redundant ?? guard. Neither affects correctness of the bug fix.

No files require special attention.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/acpx/src/runtime.ts
Line: 341-346

Comment:
**Runtime override silently dropped when key already present**

When a configured command already contains `-c model=<A>` and the runtime scope (e.g. `sessions_spawn`) supplies a *different* model `<B>`, the runtime value is silently discarded: the function returns the configured command unchanged. This is correct for the identical-value duplicate case, but a caller who genuinely wants to *switch* models at runtime will be surprised to find their override ignored with no log or error.

Consider adding a comment documenting the precedence rule, or logging a warning when the configured and runtime values diverge.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/acpx/src/runtime.ts
Line: 330-331

Comment:
**Redundant nullish coalescing**

`i + 1 < parts.length` is already verified by the outer condition, so `parts[i + 1]` is guaranteed to be a non-undefined `string` here. The `?? ""` fallback is unreachable.

```suggestion
      if (parts[i + 1]!.startsWith(`${key}=`)) {
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(acpx): prevent duplicate -c config o..." | Re-trigger Greptile

Comment on lines +341 to 346
if (override.model && !commandHasConfigKey(command, "model")) {
configArgs.push(`model=${override.model}`);
}
if (override.reasoningEffort && !commandHasConfigKey(command, "model_reasoning_effort")) {
configArgs.push(`model_reasoning_effort=${override.reasoningEffort}`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Runtime override silently dropped when key already present

When a configured command already contains -c model=<A> and the runtime scope (e.g. sessions_spawn) supplies a different model <B>, the runtime value is silently discarded: the function returns the configured command unchanged. This is correct for the identical-value duplicate case, but a caller who genuinely wants to switch models at runtime will be surprised to find their override ignored with no log or error.

Consider adding a comment documenting the precedence rule, or logging a warning when the configured and runtime values diverge.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/acpx/src/runtime.ts
Line: 341-346

Comment:
**Runtime override silently dropped when key already present**

When a configured command already contains `-c model=<A>` and the runtime scope (e.g. `sessions_spawn`) supplies a *different* model `<B>`, the runtime value is silently discarded: the function returns the configured command unchanged. This is correct for the identical-value duplicate case, but a caller who genuinely wants to *switch* models at runtime will be surprised to find their override ignored with no log or error.

Consider adding a comment documenting the precedence rule, or logging a warning when the configured and runtime values diverge.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +330 to +331
if (parts[i] === "-c" && i + 1 < parts.length) {
if ((parts[i + 1] ?? "").startsWith(`${key}=`)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant nullish coalescing

i + 1 < parts.length is already verified by the outer condition, so parts[i + 1] is guaranteed to be a non-undefined string here. The ?? "" fallback is unreachable.

Suggested change
if (parts[i] === "-c" && i + 1 < parts.length) {
if ((parts[i + 1] ?? "").startsWith(`${key}=`)) {
if (parts[i + 1]!.startsWith(`${key}=`)) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/acpx/src/runtime.ts
Line: 330-331

Comment:
**Redundant nullish coalescing**

`i + 1 < parts.length` is already verified by the outer condition, so `parts[i + 1]` is guaranteed to be a non-undefined `string` here. The `?? ""` fallback is unreachable.

```suggestion
      if (parts[i + 1]!.startsWith(`${key}=`)) {
```

How can I resolve this? If you propose a fix, please make it concise.

@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Workflow note: Future ClawSweeper reviews update this same comment in place.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Summary
The PR adds an ACPX helper to detect existing Codex ACP -c config keys, skips appending duplicate model/reasoning flags, and adds focused runtime tests.

Reproducibility: yes. source-reproducible: current main appends Codex ACP model/thinking startup -c args to a command that may already contain same-key -c values, matching the linked report. I did not run a live ACP smoke in this read-only review.

PR rating
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Summary: Not quality-ready yet because real behavior proof is missing and the patch has a blocking runtime override precedence bug.

Rank-up moves:

  • Revise the command handling so explicit runtime model/thinking overrides replace conflicting configured -c args or fail clearly.
  • Add redacted real ACPX/Codex proof showing both configured defaults and explicit runtime override behavior after the patch.
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Real behavior proof
Needs real behavior proof before merge: Missing: the PR has tests and CI notes but no redacted real ACPX/Codex terminal output, screenshot/video, linked artifact, or logs; after adding proof, update the PR body or ask for @clawsweeper re-review.

Risk before merge

  • Missing real behavior proof remains a merge gate for this external PR; tests and CI do not prove a real ACPX/Codex adapter run in the contributor's setup.
  • Merging as-is can make configured Codex -c model or -c model_reasoning_effort flags silently override explicit sessions_spawn.model or thinking requests, changing documented model-selection behavior.

Maintainer options:

  1. Preserve runtime override precedence (recommended)
    Before merge, remove or replace same-key configured Codex ACP -c args when an explicit runtime model/thinking override is supplied, and cover conflicting-value cases in tests.
  2. Accept configured-command precedence deliberately
    Maintainers could choose configured command flags as the source of truth, but that needs an explicit docs/product update because it changes the current sessions_spawn override contract.
  3. Pause until live proof exists
    If the contributor cannot provide a redacted after-fix ACPX/Codex run, pause this PR and keep the linked bug open for a maintainer-proven replacement.

Next step before merge
Needs contributor-provided live proof and a precedence fix before merge; automation cannot supply the external real-behavior proof for this PR.

Security
Cleared: The diff only changes ACPX command normalization and tests, with no dependency, workflow, permission, package-script, secret-handling, or supply-chain surface added.

Review findings

  • [P1] Preserve explicit runtime overrides — extensions/acpx/src/runtime.ts:596-600
Review details

Best possible solution:

Keep the fix ACPX-local, but parse the Codex ACP command so explicit runtime model/thinking overrides replace conflicting configured -c keys while identical values are deduplicated, with regression tests and redacted live ACPX/Codex proof.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible: current main appends Codex ACP model/thinking startup -c args to a command that may already contain same-key -c values, matching the linked report. I did not run a live ACP smoke in this read-only review.

Is this the best way to solve the issue?

No. Skipping already-present keys avoids identical duplicates, but it is not the best fix because it silently discards explicit runtime overrides that the docs define as child-session overrides.

Label justifications:

  • P2: This is a normal-priority ACPX Codex bug fix with limited blast radius, but it is not release-emergency severity.
  • merge-risk: 🚨 compatibility: The patch changes precedence between configured command flags and explicit runtime overrides, which can alter existing spawn behavior.
  • merge-risk: 🚨 auth-provider: The affected behavior controls Codex ACP model/thinking routing, so a wrong precedence rule can send work to an unintended model configuration.
  • rating: 🧂 unranked krab: Current PR rating is 🧂 unranked krab because proof is 🧂 unranked krab, patch quality is 🦪 silver shellfish, and Not quality-ready yet because real behavior proof is missing and the patch has a blocking runtime override precedence bug.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Missing: the PR has tests and CI notes but no redacted real ACPX/Codex terminal output, screenshot/video, linked artifact, or logs; after adding proof, update the PR body or ask for @clawsweeper re-review.

Full review comments:

  • [P1] Preserve explicit runtime overrides — extensions/acpx/src/runtime.ts:596-600
    When the configured Codex command already has -c model=gpt-5.4, this guard skips appending a later explicit runtime model such as sessions_spawn.model=openai-codex/gpt-5.5. Since Codex ACP startup overrides are applied through this command injection path, the PR silently runs the configured model instead of the requested runtime override; replace/remove the conflicting configured -c arg or fail clearly.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.87

What I checked:

  • Current main appends Codex ACP startup overrides: Current main builds -c model=... and -c model_reasoning_effort=... from the runtime override and appends them to the Codex ACP command when a Codex ACP session is ensured. (extensions/acpx/src/runtime.ts:582, 258524973798)
  • PR changes duplicate handling to configured-command precedence: The PR head skips appending an override whenever the command already has the same key, so a configured -c model=... prevents a different explicit runtime model override from being added to the startup command. (extensions/acpx/src/runtime.ts:596, 62f44b8afd0a)
  • Documented runtime override contract: The ACP agents docs describe sessions_spawn.model and thinking as explicit ACP child-session overrides, and say Codex ACP normalizes those values to startup config before session creation. Public docs: docs/tools/acp-agents.md. (docs/tools/acp-agents.md:559, 258524973798)
  • Dependency contract check: The inspected acpx@0.8.0 runtime applies requested models from sessionOptions.model; OpenClaw's ACPX wrapper supplies Codex model/thinking startup behavior through command config injection, so skipping the injected -c value loses the explicit runtime override on this path.
  • Real behavior proof is still absent: The PR body and comments provide tests, CI notes, and a check-test-types fix, but no after-fix real ACPX/Codex terminal output, screenshot/video, linked artifact, or redacted logs.
  • Area history routing: File history and shortlog point to Peter Steinberger as the heaviest recent ACPX runtime contributor, with Vincent Koc and Onur Solmaz also carrying related ACPX runtime/library work.

Likely related people:

  • steipete: Blame and recent file history put the current Codex ACP runtime override block and most ACPX runtime/test touches on Peter Steinberger; the PR discussion also pings this handle for review. (role: recent area contributor; confidence: high; commits: 9c5e8eb4950e, 38a673b688eb, fb61986767c7; files: extensions/acpx/src/runtime.ts, extensions/acpx/src/runtime.test.ts, extensions/acpx/package.json)
  • vincentkoc: Shortlog shows several ACPX runtime/test commits, including direct ACP adapter contract and registry-related work near this surface. (role: adjacent ACPX contributor; confidence: medium; commits: 5341d483d148, d55e580307ba, fa2a318f401e; files: extensions/acpx/src/runtime.ts, extensions/acpx/src/runtime.test.ts)
  • Onur Solmaz: History shows work consuming the acpx runtime library and earlier configurable-command ACPX changes that are adjacent to command construction behavior. (role: runtime library integration contributor; confidence: medium; commits: 154a7edb7cad, 921ebfb25e9a, 9cfc630be975; files: extensions/acpx/src/runtime.ts, extensions/acpx/src/runtime.test.ts)

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

@SymbolStar

Copy link
Copy Markdown
Contributor Author

Hi @steipete — friendly ping 🙏 CI is green now (rebased on latest main). Would appreciate a look when you get a chance!

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 20, 2026
@SymbolStar

Copy link
Copy Markdown
Contributor Author

Merged latest main, resolved 1 conflict in extensions/acpx/src/runtime.ts (export block — kept both commandHasConfigKey from this PR and isClaudeAcpCommand from main). Head: c21aac8e1383f716d98b99e985ec54aa66a1d53c. CI: re-running, mergeable=MERGEABLE, no more DIRTY.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@SymbolStar

Copy link
Copy Markdown
Contributor Author

Fixed check-test-types failure: the new test cases referenced __testing but the module exports testing (already used elsewhere in this file). Replaced __testing.* with testing.* for consistency. New HEAD: 62f44b8.

@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: acpx merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: ACPX Codex worker fails when model/thinking overrides are configured

2 participants