can1357/oh-my-pi · error · Error

Invalid Firecrawl base URL: URL credentials are not allowed

Error message

Invalid Firecrawl base URL: URL credentials are not allowed

What it means

resolveSearchUrl() rejects a configured Firecrawl base URL that embeds userinfo credentials (a username or password component, e.g. https://user:pass@host). Credentials in URLs are a security risk — they leak into logs and error messages — so the provider forbids them and expects auth to be supplied via the API key instead.

Source

Thrown at packages/coding-agent/src/web/search/providers/firecrawl.ts:46

	day: "qdr:d",
	week: "qdr:w",
	month: "qdr:m",
	year: "qdr:y",
};
function resolveSearchUrl(): string {
	const configured = process.env.FIRECRAWL_BASE_URL ?? process.env.FIRECRAWL_API_URL;
	if (!configured?.trim()) return `${FIRECRAWL_DEFAULT_BASE_URL}/search`;
	let url: URL;
	try {
		url = new URL(configured.trim());
	} catch {
		throw new Error("Invalid Firecrawl base URL: expected an HTTP or HTTPS URL");
	}
	if (url.protocol !== "http:" && url.protocol !== "https:") {
		throw new Error("Invalid Firecrawl base URL: expected an HTTP or HTTPS URL");
	}
	if (url.username || url.password) {
		throw new Error("Invalid Firecrawl base URL: URL credentials are not allowed");
	}
	url.search = "";
	url.hash = "";
	url.pathname = url.pathname.replace(/\/+$/, "");
	if (!/\/v[12]$/i.test(url.pathname)) url.pathname += "/v2";
	url.pathname += "/search";
	return url.toString();
}

export interface FirecrawlSearchParams {
	query: string;
	num_results?: number;
	recency?: SearchParams["recency"];
	/** Explicit `tbs` (custom date range); takes precedence over `recency`. */
	tbs?: string;
	signal?: AbortSignal;
	timeoutMs?: number;
	fetch?: FetchImpl;

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove the user:password@ portion from the URL, keeping only scheme://host[:port]
  2. Pass authentication the supported way: set FIRECRAWL_API_KEY so it is sent as a bearer key in the request headers
  3. If you need to traverse an authenticated proxy, configure the proxy at the environment/network level (HTTP_PROXY/HTTPS_PROXY) rather than in the base URL

Example fix

// before
FIRECRAWL_BASE_URL=https://user:secret@api.firecrawl.dev
// after
FIRECRAWL_BASE_URL=https://api.firecrawl.dev
FIRECRAWL_API_KEY=fc-...
Defensive patterns

Strategy: validation

Validate before calling

const raw = (process.env.FIRECRAWL_BASE_URL ?? "").trim();
if (raw) {
  const u = new URL(raw);
  if (u.username || u.password) {
    throw new Error("Remove user:pass@ from FIRECRAWL_BASE_URL; use FIRECRAWL_API_KEY instead");
  }
}

Type guard

function hasUrlCredentials(value: string): boolean {
  try {
    const u = new URL(value);
    return Boolean(u.username || u.password);
  } catch {
    return false;
  }
}

Try / catch

try {
  results = await firecrawlSearch(query);
} catch (err) {
  if (err instanceof Error && err.message.includes("URL credentials are not allowed")) {
    logger.error("Strip userinfo from FIRECRAWL_BASE_URL and set FIRECRAWL_API_KEY", { cause: err.message });
  } else throw err;
}

Prevention

When it happens

Trigger: FIRECRAWL_BASE_URL or FIRECRAWL_API_URL contains a `user:password@` section before the hostname, e.g. 'https://user:secret@api.firecrawl.dev' or 'http://admin:admin@localhost:3002'.

Common situations: Developers trying to pass proxy or basic-auth credentials inline in the base URL, a common pattern with some HTTP clients but not supported here; also happens when copying URLs from password-protected tunnels.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/89c3608bfcf6878a. Report an issue: GitHub.