Skip to content

fix(opencode): surface 2xx-but-not-200 HTTP status in webfetch output - #47959

Open
alexbuuuuuu wants to merge 2 commits into
anomalyco:devfrom
alexbuuuuuu:webfetch-expose-2xx-status
Open

fix(opencode): surface 2xx-but-not-200 HTTP status in webfetch output#47959
alexbuuuuuu wants to merge 2 commits into
anomalyco:devfrom
alexbuuuuuu:webfetch-expose-2xx-status

Conversation

@alexbuuuuuu

@alexbuuuuuu alexbuuuuuu commented Sep 8, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #47897

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

webfetch puts the content-type in title and returns metadata: {}. Neither
reaches the model — a completed tool part is turned into a model message from
state.output alone (session/message-v2.ts), so the model only ever sees the body.

That makes a 2xx-but-not-200 response indistinguishable from a successful fetch:

  • a 202 Accepted throttle or interstitial page (common when a shared egress IP is
    being rate-limited) arrives as if it were the page itself
  • a 204 No Content arrives as an empty page

Non-2xx is already fine — filterStatusOk fails and the status is in the error
message. The gap is 202 / 203 / 204 / 206.

This prefixes output with [HTTP <status> ...] when the status is not 200, and
records the status in metadata for the UI. 200 responses are untouched, so
existing output is unchanged.

#45937 covers the error path (keeping the specific failure message); this one covers
the success path. They don't touch the same lines.

How did you verify your code works?

  • bun test test/tool/webfetch.test.ts in packages/opencode: 7 pass / 0 fail.
  • The three new tests are discriminating: with only webfetch.ts reverted, 4 pass / 3 fail.
  • bun run typecheck in packages/opencode gives byte-identical output with and
    without my change — dev already has one pre-existing error in src/bus/global.ts.
  • prettier --check clean on both changed files.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

webfetch only hands the model `output`; `title` and `metadata` are consumed by
the UI and never reach it. A 2xx response that is not 200 - a 202 Accepted
throttle page, a 204 No Content - therefore arrives looking like the requested
content, and the model has no way to tell it should try another source.

Prefix `output` with an "[HTTP <status> ...]" notice whenever the status is not
200, and record the status in `metadata`. 200 responses are untouched, so
existing output is unchanged. Non-2xx already surfaces its status through the
error from filterStatusOk, so this closes the remaining gap.

Fixes anomalyco#47897
Copilot AI lite review requested due to automatic review settings September 8, 2026 12:19
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found one potentially related PR:

Related PR:

Why it's related: This PR is explicitly mentioned in your PR description. #45937 handles the error path for webfetch (keeping specific failure messages), while your PR #47959 handles the success path for 2xx-but-not-200 responses. Both PRs improve webfetch output visibility but address different scenarios.

No duplicate PRs found for the specific issue being fixed (#47897).

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Copilot AI left a comment

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.

🟢 Approval recommended

The change is narrowly scoped, has clear regression tests, and preserves existing 200-response output behavior.

Pull request overview

This PR improves webfetch tool output so 2xx-but-not-200 HTTP responses (e.g., 202/204/206) are distinguishable from a normal 200 in the model-visible output, while also recording the status in tool metadata for UI/consumers.

Changes:

  • Prefixes tool output with an [HTTP <status> …] notice when response.status !== 200, and sets metadata.status for all responses.
  • Adds targeted tests to ensure non-200 success statuses are annotated and 200 responses remain unchanged.
  • Documents the new notice behavior in the tool’s usage notes.
File summaries
File Description
packages/opencode/src/tool/webfetch.ts Adds non-200 status notice prefix and records HTTP status in tool metadata.
packages/opencode/test/tool/webfetch.test.ts Adds regression tests covering 202-with-body, 202-empty-body, and unchanged 200 behavior.
packages/opencode/src/tool/webfetch.txt Documents the new [HTTP <status> …] output prefix for non-200 responses.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/opencode/src/tool/webfetch.txt Outdated
Comment on lines +10 to +14
@@ -11,3 +11,4 @@ Usage notes:
- Format options: "markdown" (default), "text", or "html"
- This tool is read-only and does not modify any files
- Results may be summarized if the content is very large
- If the response status is not 200, the output starts with an "[HTTP <status> ...]" notice; the body may be a throttle or interstitial page rather than the requested content

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch - clarified in 1b11fad. The usage note now says a plain-text "[HTTP ...]" line precedes the body regardless of the requested format, and the opening description mentions it too, so format: "html" callers are not left assuming the output is strictly markup.

…s the body

The notice is prefixed regardless of the requested format, so `format: "html"`
no longer returns markup alone when the status is not 200. Say so in the tool
description instead of leaving callers to assume the output is strictly the
requested format.
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.

webfetch returns 202/204 responses as page content with no way for the model to tell

2 participants