Reject unsupported options for codex queue (#57273)

## What changed

- Validate inherited options before and after the `queue` subcommand, with explicit errors for unsupported flags and positional prompts.
- Reject `--model` and `-c model=...` because queued messages use the thread's model.
- Allow `--cd` for local server startup, but reject it with `--remote`.
- Hide unsupported inherited options from queue help and clarify the scope of startup configuration overrides.

## Testing

Add regression coverage for unsupported options in both argument scopes, model configuration overrides, remote `--cd` conflicts, and queue help output. Preserve coverage for overrides that bypass a running local daemon.

GitOrigin-RevId: 703ba26f38930a01559847e66e1af3d0d338d1e9
This commit is contained in:
Eric Traut
2026-10-26 21:37:03 +00:00
committed by copyberry
parent e963cab11a
commit bae11269eb
4 changed files with 145 additions and 21 deletions
+37 -17
View File
@@ -182,20 +182,39 @@ fn queue_rejects_empty_message() -> Result<()> {
}
#[test]
fn queue_rejects_image_attachments() -> Result<()> {
let output = std::process::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?)
.args([
"queue",
"--thread",
THREAD_ID,
"--message",
"do the thing",
"--image",
"screenshot.png",
])
.output()?;
assert!(!output.status.success());
assert!(String::from_utf8(output.stderr)?.contains("does not support image attachments"));
fn queue_rejects_unsupported_options() -> Result<()> {
let codex_home = TempDir::new()?;
for (args, expected) in [
("queue --image screenshot.png", "image attachments"),
("queue --model other-model", "`--model`"),
("--oss queue", "`--oss`"),
("queue --local-provider ollama", "`--local-provider`"),
(
"queue --dangerously-bypass-hook-trust",
"`--dangerously-bypass-hook-trust`",
),
(
"-c model=other queue -c analytics.enabled=false",
"`model` config override",
),
("queue -s read-only", "`--sandbox`"),
("--approve-for-me queue", "`--approve-for-me`"),
("prompt queue", "positional prompt; use `--message`"),
("-C . queue --remote unix://", "`--cd` with `--remote`"),
("--remote unix:// queue -C .", "`--cd` with `--remote`"),
] {
let output = std::process::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?)
.env("CODEX_HOME", codex_home.path())
.args(args.split_whitespace())
.args(["--thread", THREAD_ID, "--message", "do the thing"])
.output()?;
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr)?;
assert!(
stderr.contains("`codex queue`") && stderr.contains(expected),
"{args:?}: {stderr}"
);
}
Ok(())
}
@@ -631,8 +650,10 @@ async fn queue_rejects_overrides_that_bypass_local_daemon() -> Result<()> {
.env("CODEX_HOME", codex_home.path())
.args([
"queue",
"-C",
".",
"-c",
"model=\"test-model\"",
"analytics.enabled=false",
"--thread",
THREAD_ID,
"--message",
@@ -640,12 +661,11 @@ async fn queue_rejects_overrides_that_bypass_local_daemon() -> Result<()> {
])
.output()
.await?;
server.await??;
assert!(!output.status.success());
assert!(
String::from_utf8(output.stderr)?
.contains("embedded app server while a local app-server daemon is running")
);
server.await??;
Ok(())
}