upstash/context7 · error · Context7UrlError
invalid_url
invalid_url
Error message
Context7 client was passed an invalid URL. You should pass a URL starting with http:// or https://. Received: "${url}". What it means
Context7UrlError (code "invalid_url") thrown in the client constructor when the baseUrl does not start with http:// or https://. The trailing slash is stripped first, then isHttpUrl validates the scheme.
Source
Thrown at packages/sdk/src/http/index.ts:57
timeout: number | false;
keepAlive: boolean;
};
public readonly retry: RetryPolicy;
private readonly fetch: Context7Fetch;
private readonly onResponse?: (metadata: Context7ResponseMetadata) => void;
public constructor(config: HttpClientConfig) {
this.options = {
cache: config.cache,
signal: config.signal,
timeout: config.timeout ?? DEFAULT_TIMEOUT,
keepAlive: config.keepAlive ?? true,
};
validateTimeout(this.options.timeout);
this.baseUrl = config.baseUrl.replace(/\/$/, "");
if (!isHttpUrl(this.baseUrl)) throw new Context7UrlError(this.baseUrl);
this.headers = { "Content-Type": "application/json", ...config.headers };
if (!config.fetch && !globalThis.fetch) {
throw new TypeError("A fetch implementation is required");
}
this.fetch = config.fetch ?? globalThis.fetch.bind(globalThis);
this.onResponse = config.onResponse;
this.retry = createRetryPolicy(config.retry);
}
public async request<TResult>(request: Context7Request): Promise<Context7Response<TResult>> {
const method = request.method ?? "POST";
const abortState = createAbortState(
[resolveSignal(this.options.signal), request.signal],
request.timeout ?? this.options.timeout
);
const init: RequestInit = {
cache: normalizeCache(request.cache ?? this.options.cache),View on GitHub (pinned to 80e681a507)
Solutions
- Prefix the URL with https:// (or http:// for local dev): baseUrl: 'https://context7.com/api'.
- Validate the value before constructing: new URL(u) and check protocol is http: or https:.
- Fix the environment variable/config file so it contains the full absolute URL.
- Normalize trailing slashes if desired; the constructor already strips them — only the scheme matters.
Example fix
// before
new Context7Client({ baseUrl: process.env.CONTEXT7_URL }); // 'context7.com' -> invalid_url
// after
const raw = process.env.CONTEXT7_URL;
const baseUrl = raw.startsWith('http') ? raw : `https://${raw}`;
new Context7Client({ baseUrl }); Defensive patterns
Strategy: validation
Validate before calling
function assertHttpUrl(u: string): void {
const parsed = new URL(u);
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
throw new Error(`baseUrl must start with http:// or https://, got: ${u}`);
}
} Type guard
function isHttpUrl(u: string): boolean {
try {
const p = new URL(u);
return p.protocol === 'http:' || p.protocol === 'https:';
} catch {
return false;
}
} Try / catch
try {
const client = new Context7Client({ baseUrl });
} catch (e) {
if (e instanceof Context7Error && e.code === 'invalid_url') {
console.error(`Fix CONTEXT7_BASE_URL (needs scheme): ${e.message}`);
}
throw e;
} Prevention
- Always include https:// in config files and env vars for base URLs.
- Run assertHttpUrl at app startup, before client construction.
- Add a config schema validation step (zod .url()) for environment-derived values.
When it happens
Trigger: new Context7Client({ baseUrl: 'context7.com/api' }) or 'localhost:8080' or an empty string — any URL without an http:// or https:// scheme.
Common situations: Omitting the scheme because browsers auto-complete it, reading baseUrl from env/config without scheme, accidentally passing a path or relative URL, or typos like 'hhttps://'.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid MCP_MAX_SUBSCRIPTIONS; using the default of ${DEFAUL
- timeout must be a positive number or false
- retry.retries must be a non-negative integer
- Unsafe skill name: ${JSON.stringify(skillName)}
- Skill name "${skillName}" escapes the skills root
AI-assisted analysis of upstash/context7@80e681a507 (2026-09-08).
Data as JSON: /api/errors/41ced66abaa6d06e.
Report an issue: GitHub.