diff --git a/packages/adapters/codex-local/src/server/codex-args.test.ts b/packages/adapters/codex-local/src/server/codex-args.test.ts index 9e9c614a56..931dea19ba 100644 --- a/packages/adapters/codex-local/src/server/codex-args.test.ts +++ b/packages/adapters/codex-local/src/server/codex-args.test.ts @@ -156,4 +156,45 @@ describe("buildCodexExecArgs", () => { "-", ]); }); + + it("does not add a second --skip-git-repo-check when extraArgs already carry it", () => { + const result = buildCodexExecArgs( + { + model: "gpt-5.5", + extraArgs: ["--skip-git-repo-check"], + }, + { skipGitRepoCheck: true }, + ); + + expect(result.args.filter((arg) => arg === "--skip-git-repo-check")).toHaveLength(1); + expect(result.args).toEqual([ + "exec", + "--json", + "--model", + "gpt-5.5", + "--skip-git-repo-check", + "-", + ]); + }); + + it("does not add a second --skip-git-repo-check when the legacy args field carries it", () => { + const result = buildCodexExecArgs( + { + model: "gpt-5.5", + args: ["--skip-git-repo-check"], + }, + { skipGitRepoCheck: true }, + ); + + expect(result.args.filter((arg) => arg === "--skip-git-repo-check")).toHaveLength(1); + }); + + it("keeps the operator's --skip-git-repo-check when the sandbox injection is not requested", () => { + const result = buildCodexExecArgs({ + model: "gpt-5.5", + extraArgs: ["--skip-git-repo-check"], + }); + + expect(result.args.filter((arg) => arg === "--skip-git-repo-check")).toHaveLength(1); + }); }); diff --git a/packages/adapters/codex-local/src/server/codex-args.ts b/packages/adapters/codex-local/src/server/codex-args.ts index 475345514f..db9b349c0a 100644 --- a/packages/adapters/codex-local/src/server/codex-args.ts +++ b/packages/adapters/codex-local/src/server/codex-args.ts @@ -5,6 +5,8 @@ import { normalizeCodexModel, } from "../index.js"; +const SKIP_GIT_REPO_CHECK_FLAG = "--skip-git-repo-check"; + export type BuildCodexExecArgsResult = { args: string[]; model: string; @@ -52,7 +54,14 @@ export function buildCodexExecArgs( const extraArgs = readExtraArgs(record); const args = ["exec", "--json"]; - if (options.skipGitRepoCheck) args.push("--skip-git-repo-check"); + // Codex rejects a repeated `--skip-git-repo-check` ("cannot be used multiple + // times"). The adapter injects this flag for sandbox execution, so when an + // operator's extraArgs already carry it the injection would abort the run + // with exit code 2. Skip the injection in that case and let the operator's + // copy stand. + if (options.skipGitRepoCheck && !extraArgs.includes(SKIP_GIT_REPO_CHECK_FLAG)) { + args.push(SKIP_GIT_REPO_CHECK_FLAG); + } if (search) args.unshift("--search"); if (bypass) args.push("--dangerously-bypass-approvals-and-sandbox"); if (model) args.push("--model", model);