upstash/context7 · error · Context7UrlError

Context7UrlError

Error message

Context7UrlError

What it means

Context7UrlError is thrown by the HTTP client constructor when the configured baseUrl, after trimming a trailing slash, is not a valid HTTP(S) URL (per isHttpUrl). It signals a malformed or wrongly-schemed base URL at client initialization time.

Solutions

  1. Set baseUrl to a full URL with scheme, e.g. 'https://context7.com'
  2. Add 'https://' if you only supplied a hostname
  3. Trim whitespace and remove stray characters from the configured value
  4. Validate the URL with new URL(value) and checking ^https?: before constructing the client

Example fix

// before
const client = new Context7Client({ baseUrl: 'context7.com' });
// after
const client = new Context7Client({ baseUrl: 'https://context7.com' });
Defensive patterns

Strategy: validation

Validate before calling

function isValidBaseUrl(v) {
  try { const u = new URL(v); return u.protocol === 'http:' || u.protocol === 'https:'; } catch { return false; }
}

Type guard

function isHttpUrl(v: unknown): v is string {
  if (typeof v !== 'string') return false;
  try { const u = new URL(v); return u.protocol === 'http:' || u.protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  const client = new Context7Client({ baseUrl });
} catch (e) {
  if (e instanceof Context7UrlError) {
    console.error(`baseUrl "${e.url ?? baseUrl}" is not a valid http(s) URL`);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing the client with baseUrl values like 'localhost:3000' (no scheme), 'ftp://x', 'context7.com' without protocol, an empty string after stripping, or strings containing spaces/invalid characters.

Common situations: Omitting the 'https://' scheme in config files; building the URL by string concatenation that drops the scheme; using a placeholder value left in .env; passing a path like '/api' instead of a full origin.

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


AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16). Data as JSON: /api/errors/94844346ef609e77. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/src/http/index.ts:59

    keepAlive: boolean;
  };
  public readonly retry: RetryPolicy;

  private readonly fetch: Context7Fetch;
  private readonly authToken?: string | AuthTokenProvider;
  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 };
    this.authToken = config.authToken;
    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
    );
    try {

View on GitHub (pinned to 4416fb855b)