paperclipai/paperclip · error · Error
Invalid URL: ${urlString}
Error message
Invalid URL: ${urlString} What it means
validateAndResolveFetchUrl could not parse the plugin-supplied URL string with the URL constructor. This is the SSRF-guard input gate for plugin fetch: the raw urlString is malformed (bad scheme, spaces, etc.) before any protocol or DNS checks run.
Source
Thrown at server/src/services/plugin-host-services.ts:165
* resolve to a safe IP during validation, then to a private IP when fetch() runs.
*
* @returns Request-routing metadata used to connect directly to the resolved IP
* while preserving the original hostname for HTTP Host and TLS SNI.
*/
interface ValidatedFetchTarget {
parsedUrl: URL;
resolvedAddress: string;
hostHeader: string;
tlsServername?: string;
useTls: boolean;
}
async function validateAndResolveFetchUrl(urlString: string): Promise<ValidatedFetchTarget> {
let parsed: URL;
try {
parsed = new URL(urlString);
} catch {
throw new Error(`Invalid URL: ${urlString}`);
}
if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) {
throw new Error(
`Disallowed protocol "${parsed.protocol}" — only http: and https: are permitted`,
);
}
// Resolve the hostname to an IP and check for private ranges.
// We pin the resolved IP into the URL to eliminate the TOCTOU window
// between DNS resolution here and the second resolution fetch() would do.
const originalHostname = parsed.hostname.replace(/^\[|\]$/g, ""); // strip IPv6 brackets
const hostHeader = parsed.host; // includes port if non-default
// Race the DNS lookup against a timeout to prevent indefinite hangs
// when DNS is misconfigured or unresponsive.
const dnsPromise = dnsLookup(originalHostname, { all: true });
const timeoutPromise = new Promise<never>((_, reject) => {View on GitHub (pinned to a7e689b3c3)
Solutions
- Provide a well-formed URL string for the plugin host service request.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/services/plugin-host-services.ts:165 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18).
Data as JSON: /api/errors/23d9263d4984a26d.
Report an issue: GitHub.