headroomlabs-ai/headroom · error · Error
Invalid proxyUrl: "${proxyUrl}"
Error message
Invalid proxyUrl: "${proxyUrl}" What it means
normalizeAndValidateProxyUrl() could not parse the configured proxyUrl with the WHATWG URL constructor — the string is not a valid absolute URL at all (before any scheme/host checks happen). Typical culprits are missing scheme, stray characters, or a bare host:port.
Source
Thrown at plugins/openclaw/src/proxy-manager.ts:409
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
timeout: 5000,
});
if (result.error || result.status !== 0) return null;
const prefix = (result.stdout ?? "").trim();
return prefix.length > 0 ? prefix : null;
} catch {
return null;
}
}
}
/** Parse a URL, returning the parsed object or throwing a descriptive error. */
function parseProxyUrl(proxyUrl: string): URL {
try {
return new URL(proxyUrl);
} catch {
throw new Error(`Invalid proxyUrl: "${proxyUrl}"`);
}
}
export function normalizeAndValidateProxyUrl(proxyUrl: string): string {
const parsed = parseProxyUrl(proxyUrl);
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
throw new Error("proxyUrl must use http:// or https://");
}
if (parsed.pathname !== "/" || parsed.search || parsed.hash) {
throw new Error("proxyUrl must not include a path, query, or hash");
}
return parsed.origin;
}
/** Returns true if the URL points to a local address (localhost or 127.0.0.1). */View on GitHub (pinned to 322425c43b)
Solutions
- Include the scheme: use "http://127.0.0.1:8787" not "127.0.0.1:8787"
- Trim whitespace/newlines when the URL comes from env vars or config files
- Sanity-check the value in a REPL: new URL(value) must not throw before passing it in
Example fix
// before
manager.configure({ proxyUrl: "localhost:8787" }); // throws
// after
manager.configure({ proxyUrl: "http://localhost:8787" }); Defensive patterns
Strategy: type-guard
Validate before calling
function isParseableUrl(value: string): boolean {
try {
new URL(value);
return true;
} catch {
return false;
}
}
if (!isParseableUrl(proxyUrl)) {
throw new Error(`proxyUrl '${proxyUrl}' is not a valid absolute URL — include the scheme, e.g. http://...`); Type guard
function isValidAbsoluteUrl(value: string): value is `http://${string}` | `https://${string}` {
try {
const u = new URL(value);
return u.protocol === "http:" || u.protocol === "https:";
} catch {
return false;
}
} Prevention
- Always include the scheme (http:// or https://) — bare host:port values do not parse as URLs here
- Trim env-var-derived URLs to remove stray newlines before use
- Run config through normalizeAndValidateProxyUrl() at load time so bad URLs fail fast with one clear error
When it happens
Trigger: Passing proxyUrl values like "localhost:8787" (interpreted as scheme, actually invalid here), "127.0.0.1:8787", "headroom proxy", or a string with whitespace/control characters to normalizeAndValidateProxyUrl().
Common situations: Bare host:port copied from CLI docs; trailing newline from an env var or config file; URL assembled by string concatenation with a typo; scheme accidentally deleted during editing.
Related errors
- proxyUrl must use http:// or https://
- proxyUrl must not include a path, query, or hash
- proxyPort must be an integer between 1 and 65535
- Invalid {TOOL_INJECTION_STICKY_ENV}={normalized!r}; expected
- unsupported headroom-bench proxy mode: {raw_mode!r}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/e3504effbe17137c.
Report an issue: GitHub.