ErrLookupBackground articles › "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format

"Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format

"Invalid URL" errors happen when a library parses a URL before using it and the string fails: a missing scheme, unencoded whitespace, an unexpected path shape, or a host:port pasted into the wrong field. This family covers the parse-time and format-time URL validators across dozens of open-source tools — from JavaScript's new URL() throwing TypeError, to Ruby's URI::InvalidURIError, to regex guards that demand https://github.com/owner/repo or /stats/matches/mapstatsid/:id/:slug exactly — and explains what each validator actually checks and how to fix the string.

Distilled from 94 documented records across 39 repositories.

Background

This family sits at the input-validation boundary of libraries that accept a URL from a user, a config file, or another program. Before making any network request, the library parses the string — with the WHATWG URL constructor in JavaScript (mastra, worldmonitor, 9router, danbooru's upload helper), Ruby's URI.parse (sure, grav via parse_url, october via RouterHelper), Go's url.Parse (siyuan), Rust's reqwest::Url (zeroclaw), or Python's urlparse (chroma) — or applies a purpose-built regex that encodes the only URL shape the feature can handle. The error fires when parsing fails outright, when the parsed result is missing a required component (scheme, host, owner/repo, numeric ID), or when the value violates a deliberate policy like https-only or whitespace-free.

Three distinct layers of strictness live under one message. The weakest is pure parseability: does the string survive the URL constructor at all? Relative paths like /pro or /callback fail here because new URL() requires an absolute URL, and control characters, unencoded spaces, and truncated pastes fail in every language. The middle tier is structural: the URL parses but lacks a required part — no scheme ("localhost:20128" is famously ambiguous because browsers would parse localhost as the scheme), no host after https://, a GitHub URL with fewer than owner/repo segments, a Hugging Face URL that ends at the repo root with no filename. The strongest tier is policy: the URL is perfectly valid but the wrong kind. danbooru only accepts http(s), forem's Parler tag requires an exact https://www.parler.io/audio/...mp3 shape, onetimesecret rejects http:// and data: URIs for tenant branding, and zeroclaw refuses any interior whitespace before even checking the scheme.

From the caller's side, the confusion comes from the gap between 'valid URL' as humans use it and what the specific validator demands. A developer pastes www.example.com/image.png or a git@github.com:owner/repo.git SSH remote — both meaningful, both wrong for these APIs. Some errors are also deliberate fail-closed security controls, not mere format checks: zeroclaw rejects whitespace because unencoded spaces can smuggle or corrupt headers; worldmonitor's returnUrl and callbackUrl checks are open-redirect defenses; the career-ops installer restricts plugins to pinned GitHub HTTPS URLs for supply-chain auditing. Reading the message as 'this library wants a narrower URL format than what I passed' is the key to fixing it.

How the check is implemented shapes what you see. WHATWG parsers (used across the JavaScript records) throw on unparseable input but accept surprising things — kiro:// passes because it has a scheme; localhost:PORT is misparsed rather than rejected. Ruby's URI.parse accepts scheme-less strings silently (host ends up nil), so libraries that care must add an is_a?(URI::HTTP) check on the class, which is why sure's Anthropic setting demands an explicit http(s) scheme. Regex validators fail fast with the exact offending URL in the message, and a few records (chroma's host="localhost:8000/api" parsed as scheme 'localhost', angular's http://host:8080:9090 double-port) show how a valid-looking string lands in an unexpected branch of a lenient parser. The same phrase 'invalid URL' therefore covers everything from an unencoded space to a missing trailing slash after a numeric ID.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 74 more across the corpus — use search.

Honest provenance: generated on 2026-08-31 from AI-assisted analysis of the linked records. See how records are made.