{"record":{"id":"89c3608bfcf6878a","repo":"can1357/oh-my-pi","slug":"invalid-firecrawl-base-url-url-credentials-are-no","errorCode":null,"errorMessage":"Invalid Firecrawl base URL: URL credentials are not allowed","messagePattern":"Invalid Firecrawl base URL: URL credentials are not allowed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/providers/firecrawl.ts","lineNumber":46,"sourceCode":"\tday: \"qdr:d\",\n\tweek: \"qdr:w\",\n\tmonth: \"qdr:m\",\n\tyear: \"qdr:y\",\n};\nfunction resolveSearchUrl(): string {\n\tconst configured = process.env.FIRECRAWL_BASE_URL ?? process.env.FIRECRAWL_API_URL;\n\tif (!configured?.trim()) return `${FIRECRAWL_DEFAULT_BASE_URL}/search`;\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(configured.trim());\n\t} catch {\n\t\tthrow new Error(\"Invalid Firecrawl base URL: expected an HTTP or HTTPS URL\");\n\t}\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n\t\tthrow new Error(\"Invalid Firecrawl base URL: expected an HTTP or HTTPS URL\");\n\t}\n\tif (url.username || url.password) {\n\t\tthrow new Error(\"Invalid Firecrawl base URL: URL credentials are not allowed\");\n\t}\n\turl.search = \"\";\n\turl.hash = \"\";\n\turl.pathname = url.pathname.replace(/\\/+$/, \"\");\n\tif (!/\\/v[12]$/i.test(url.pathname)) url.pathname += \"/v2\";\n\turl.pathname += \"/search\";\n\treturn url.toString();\n}\n\nexport interface FirecrawlSearchParams {\n\tquery: string;\n\tnum_results?: number;\n\trecency?: SearchParams[\"recency\"];\n\t/** Explicit `tbs` (custom date range); takes precedence over `recency`. */\n\ttbs?: string;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tfetch?: FetchImpl;","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/providers/firecrawl.ts#L28-L64","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Remove the user:password@ portion from the URL, keeping only scheme://host[:port]","Pass authentication the supported way: set FIRECRAWL_API_KEY so it is sent as a bearer key in the request headers","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"],"exampleFix":"// before\nFIRECRAWL_BASE_URL=https://user:secret@api.firecrawl.dev\n// after\nFIRECRAWL_BASE_URL=https://api.firecrawl.dev\nFIRECRAWL_API_KEY=fc-...","handlingStrategy":"validation","validationCode":"const raw = (process.env.FIRECRAWL_BASE_URL ?? \"\").trim();\nif (raw) {\n  const u = new URL(raw);\n  if (u.username || u.password) {\n    throw new Error(\"Remove user:pass@ from FIRECRAWL_BASE_URL; use FIRECRAWL_API_KEY instead\");\n  }\n}","typeGuard":"function hasUrlCredentials(value: string): boolean {\n  try {\n    const u = new URL(value);\n    return Boolean(u.username || u.password);\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  results = await firecrawlSearch(query);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"URL credentials are not allowed\")) {\n    logger.error(\"Strip userinfo from FIRECRAWL_BASE_URL and set FIRECRAWL_API_KEY\", { cause: err.message });\n  } else throw err;\n}","preventionTips":["Never embed basic-auth credentials in configured URLs — always use the provider's key-based auth (FIRECRAWL_API_KEY)","Lint config files for the `@` userinfo pattern in URLs before deployment","Use HTTP_PROXY/HTTPS_PROXY for authenticated proxy traversal instead of inline URL credentials","Sanitize URLs in logs; credential-bearing URLs that fail here would otherwise leak secrets"],"tags":["configuration","security","url-validation"],"backgroundTag":"credentials-in-url","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}