Skip to content

fix(acp): name the method in request-timeout errors - #4733

Open
TheSmokeDev wants to merge 2 commits into
block:mainfrom
TheSmokeDev:fix/acp-timeout-names-its-method
Open

fix(acp): name the method in request-timeout errors#4733
TheSmokeDev wants to merge 2 commits into
block:mainfrom
TheSmokeDev:fix/acp-timeout-names-its-method

Conversation

@TheSmokeDev

Copy link
Copy Markdown

Problem

AcpError::Timeout carries only a Duration, so every request timeout produces the same sentence regardless of which call hung:

Request timeout — agent did not respond within 60s

That is the message users report, and it is not enough to place the fault. Sessions are created lazily inside the prompt task, so from the outside a stalled session/new and a stalled session/prompt are indistinguishable — even though one is bounded at REQUEST_TIMEOUT (60s) and the other at DEFAULT_IDLE_TIMEOUT_SECS (900s).

Concretely: diagnosing #4098 ("every managed prompt hangs until 60s") required tracing two codebases and reasoning backwards from the timeout constants to establish that only session/new could produce that number. The error itself should have said so.

Change

send_request already has the method in hand, and it is &'static str at every call site, so carrying it costs nothing:

Request timeout — agent did not respond to session/new within 60s

The two directly-constructed timeouts in pool.rs name theirs as well (session/set_model, session/set_config_option), so no timeout in the crate is anonymous.

Match sites become Timeout { .. }. Nothing else changes — the transport-class error classification in lib.rs and the retry handling in pool.rs behave exactly as before.

Verification

On Windows: cargo check -p buzz-acp, cargo clippy -p buzz-acp --all-targets (0 warnings) and cargo fmt -p buzz-acp -- --check (no diffs) all clean.

Not offering the crate's test suite as evidence: on this box it is non-deterministic against untouched main (different failures per run, consistent with #2492), so a before/after comparison would be noise rather than a receipt.

Note on a related asymmetry

Not changed here, but worth flagging while you have the file open: session/new gets 60s while the prompt it precedes gets 900s idle / 7200s hard. An agent that legitimately needs ~90s to provision a session can therefore never succeed on any runtime, no matter how patient the prompt budget is. Happy to open that separately if it's worth addressing.

Related: #4098. Duplicates: searched open PRs for AcpError::Timeout and request timeout — none found.

`AcpError::Timeout` carried only a `Duration`, so every timeout produced
the same sentence regardless of which call actually hung:

    Request timeout — agent did not respond within 60s

That is the message a user reports, and it is not enough to place the
fault. Sessions are created lazily inside the prompt task, so a stalled
`session/new` and a stalled `session/prompt` look identical from the
outside — one of them is bounded at 60s and the other at 900s idle, and
the operator cannot tell which they hit. Diagnosing block#4098 needed a trace
across two codebases and the timeout constants to work out that only
`session/new` could produce that number.

`send_request` already has the method in hand, and it is `&'static str`
at every call site, so carrying it costs nothing:

    Request timeout — agent did not respond to session/new within 60s

The two directly-constructed timeouts in `pool.rs` name theirs too
(`session/set_model`, `session/set_config_option`), so no timeout in the
crate is anonymous. Match sites become `Timeout { .. }`; nothing else
changes, and the classification in `lib.rs` and `pool.rs` behaves
exactly as before.

Verified on Windows: `cargo check`, `cargo clippy --all-targets` (0
warnings) and `cargo fmt --check` clean for the crate. Not offering the
crate's test suite as evidence: on this box it is non-deterministic
against untouched main (consistent with block#2492).

Signed-off-by: SmokeDev <test@test.com>
@TheSmokeDev
TheSmokeDev requested a review from a team as a code owner August 4, 2026 15:07

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6f9870465

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/buzz-acp/src/pool.rs Outdated
);
return Err(AcpError::Timeout(MODEL_SWITCH_TIMEOUT));
return Err(AcpError::Timeout {
method: "session/set_model",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Report the config-option method on its outer timeout

When ModelSwitchMethod::ConfigOption takes longer than the 5-second outer timeout, this branch reports session/set_model even though the request was actually session/set_config_option. That preserves an incorrect method name in the user-facing timeout this change is intended to disambiguate; select the method from the ModelSwitchMethod variant here.

Useful? React with 👍 / 👎.

…timeout

`apply_model_switch` serves both `ModelSwitchMethod` variants —
ConfigOption sends `session/set_config_option`, SetModel sends
`session/set_model` — but the outer-timeout branch hardcoded
`session/set_model`, so a ConfigOption switch that blew the 5s budget
would name a method it never sent.

That is worse than the anonymous timeout this PR set out to fix: a wrong
name sends whoever reads it looking in the wrong place. Derived from the
variant instead. `method_label` beside it stays what it was — prose for
humans, not an RPC name.

Caught by the automated review on this PR.

Signed-off-by: SmokeDev <test@test.com>
@TheSmokeDev

Copy link
Copy Markdown
Author

Good catch — fixed in 0b0d854.

apply_model_switch serves both ModelSwitchMethod variants, so hardcoding session/set_model in the outer-timeout branch would have named a method the ConfigOption path never sent. That is worse than the anonymous timeout this PR set out to fix: a wrong name sends whoever reads it looking in the wrong place.

Now derived from the variant:

let rpc_method = match method {
    ModelSwitchMethod::ConfigOption { .. } => "session/set_config_option",
    ModelSwitchMethod::SetModel { .. } => "session/set_model",
};

method_label beside it stays as it was — prose for humans, not an RPC name. cargo check, clippy --all-targets (0 warnings) and fmt --check still clean.

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