Skip to content

fix(agent): surface err.cause in uploadFromUrl tool error messages#1672

Merged
nevo-david merged 1 commit into
mainfrom
fix/upload-from-url-surface-cause
Jul 5, 2026
Merged

fix(agent): surface err.cause in uploadFromUrl tool error messages#1672
nevo-david merged 1 commit into
mainfrom
fix/upload-from-url-surface-cause

Conversation

@giladresisi

Copy link
Copy Markdown
Collaborator

Why

undici's fetch() rejects network-level failures (DNS, TLS, connection refused, SSRF-dispatcher block) with a generic TypeError('fetch failed') and puts the actual reason in err.cause — see lib/web/fetch/index.js#L271:

p.reject(new TypeError('fetch failed', { cause: response.error }))

The uploadFromUrl tool's catch block (added in #1649) only surfaced err.message, so the agent — and the user — saw a bare fetch failed with no indication of why the URL couldn't be fetched.

What

Append err.cause.message to the { error } result when present, e.g. fetch failed (getaddrinfo ENOTFOUND example.com) instead of just fetch failed. Error.cause isn't in the es2020 lib typings this repo compiles against, hence the cast; the access is guarded so a missing or empty cause changes nothing.

Reproduction & validation

Pre-fix: a fetch rejection surfaced only as the bare Failed to upload media from URL: fetch failed.

Post-fix, live via the uploadFromUrl agent tool over MCP:

http://no-such-host-cause-test.invalid/a.jpg
  ->  {"error":"Failed to upload media from URL: fetch failed (getaddrinfo ENOTFOUND no-such-host-cause-test.invalid)"}

Together with the companion SSRF literal-IP fix (#1671) — the two compose to give an actionable reason for blocked internal addresses:

http://192.168.1.1/a.jpg
  ->  {"error":"Failed to upload media from URL: fetch failed (Blocked IP)"}

Relation to #1671

Independent files, independently mergeable. This PR makes #1671's SSRF block (and every other fetch rejection on this path) legible in the agent's message; #1671 stands on its own without it.

🤖 Generated with Claude Code

undici's fetch() rejects network-level failures (DNS, TLS, connection
refused, SSRF-dispatcher block) with a generic TypeError('fetch failed')
and puts the actual reason in err.cause:
https://github.com/nodejs/undici/blob/2dc7e189dc6bc32097f7c926b2818d6e69b3f2a8/lib/web/fetch/index.js#L271

Append that cause message to the { error } result introduced in #1649 so
the agent can tell the user why a URL couldn't be fetched, e.g.
"fetch failed (getaddrinfo ENOTFOUND example.com)" instead of just
"fetch failed".

Error.cause isn't in the es2020 lib typings this repo compiles against,
hence the cast; guarded so a missing or empty cause changes nothing.

Reproduced (pre-fix): a fetch rejection surfaced only as the bare
"Failed to upload media from URL: fetch failed", with no indication of
the underlying DNS/TLS/SSRF reason.

Validated (post-fix), live via the uploadFromUrl agent tool over MCP:
  http://no-such-host-cause-test.invalid/a.jpg
    -> {"error":"Failed to upload media from URL: fetch failed (getaddrinfo ENOTFOUND no-such-host-cause-test.invalid)"}

Validated together with the companion SSRF literal-IP fix (both applied):
  http://192.168.1.1/a.jpg
    -> {"error":"Failed to upload media from URL: fetch failed (Blocked IP)"}

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@postiz-contribution postiz-contribution Bot added the contribution:approved Approved contributor label Jul 3, 2026
@postiz-contribution

Copy link
Copy Markdown

Contribution-checker quality warning
Heuristic score: 10/100 (low). This is a non-blocking warning surfaced by the project's quality settings.

Heuristics that flagged:

  • Excessive inline code references: 15 inline refs (>3)
  • PR doesn't use the repo's PR template: 5 required checkbox items missing (max 1, match ≥80%)
  • Body adds too many extra headers beyond the template: 4 extra headers (>1)
  • AI watermark phrase: Matched: "Generated with Claude Code"
  • Commit message too long: Longest: 1370 chars

If this is a genuine contribution, please add detail to your PR description and tighten the diff scope before reviewers look at it.

@postiz-agent

postiz-agent Bot commented Jul 3, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@nevo-david nevo-david merged commit 9b4904d into main Jul 5, 2026
11 checks passed
@nevo-david nevo-david deleted the fix/upload-from-url-surface-cause branch July 5, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution:approved Approved contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants