abhigyanpatwari/GitNexus · error · Error
LLM base URL must use http:// or https://
Error message
LLM base URL must use http:// or https:// (got ${parsed.protocol}) What it means
validateLLMBaseUrl successfully parsed the base URL but its protocol is neither http: nor https:. The message echoes only parsed.protocol (never the full URL) to avoid leaking embedded credentials. This guard blocks file://, data:, javascript:, ws:, ftp: and every other scheme (CWE-918 hardening), because the fetch-based LLM client must only talk to HTTP endpoints.
Solutions
- Change the scheme to https:// (or http:// for localhost): `--base-url https://api.example.com/v1`
- Fix the typo in the scheme (htps://, httpss://, etc.)
- For local servers use `http://localhost:PORT/v1` which passes the insecure-host check automatically
Example fix
# before gitnexus wiki --provider custom --base-url ws://localhost:8080/v1 # after gitnexus wiki --provider custom --base-url http://localhost:8080/v1
Defensive patterns
Strategy: validation
Validate before calling
const allowed = new Set(['http:', 'https:']);
const proto = (() => { try { return new URL(baseUrl).protocol; } catch { return null; } })();
if (proto && !allowed.has(proto)) throw new Error(`Unsupported scheme ${proto}; use https://`); Type guard
function isHttpUrl(value: string): boolean {
try { return ['http:', 'https:'].includes(new URL(value).protocol); } catch { return false; }
} Try / catch
try {
validateLLMBaseUrl(baseUrl);
} catch (err) {
if (err instanceof Error && err.message.startsWith('LLM base URL must use http:// or https://')) {
// rewrite ws://→http:// or file:// rejection; fix at the config source
}
} Prevention
- Restrict provider-config UIs/CLIs to http(s) schemes at input time
- When templating URLs from variables, default the scheme to https
- Unit-test config builders asserting the final protocol is http: or https:
When it happens
Trigger: Passing `--base-url file:///...`, `ws://host:8080/v1`, `ftp://...`, or a typo like `htps://` that parses to an unexpected scheme; a provider preset that accidentally produced a WebSocket URL.
Common situations: Pointing at a WebSocket endpoint of a self-hosted server; typo'd scheme; pasting a data: or file: URI by accident; scripts templating the scheme from a variable that is empty or 'ws'.
Related errors
- Insecure http:// LLM base URLs are only allowed for…
- Invalid LLM base URL: must be a well-formed http:// or…
- --allow-insecure-connection /…
- Azure content filter blocked this request. The prompt…
- Claude CLI not found. Install Claude Code and ensure…
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/1a4e8abf277da2b8.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/wiki/llm-client.ts:252
* clear error rather than an opaque network error.
*/
export function validateLLMBaseUrl(
baseUrl: string,
allowedInsecureHttpHosts: readonly string[] = parseLLMAllowedInsecureHttpHosts(
process.env[LLM_ALLOW_INSECURE_CONNECTION_ENV],
),
): void {
let parsed: URL;
try {
parsed = new URL(baseUrl);
} catch {
// Do not include the raw input in the message — it may contain credentials.
throw new Error('Invalid LLM base URL: must be a well-formed http:// or https:// URL');
}
if (!['https:', 'http:'].includes(parsed.protocol)) {
// Use parsed.protocol only (scheme), not the full URL, to avoid leaking credentials.
throw new Error(`LLM base URL must use http:// or https:// (got ${parsed.protocol})`);
}
if (parsed.protocol === 'http:') {
// Node's URL parser preserves IPv6 brackets in hostname (e.g. "[::1]"),
// so strip them before comparing to bare address literals.
const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, '');
const allowedHosts = new Set(allowedInsecureHttpHosts.map(normalizeAllowedInsecureHttpHost));
if (host !== 'localhost' && host !== '127.0.0.1' && host !== '::1' && !allowedHosts.has(host)) {
// Use parsed.origin (scheme+host+port, no credentials) instead of the full URL.
throw new Error(
`Insecure http:// LLM base URLs are only allowed for localhost/127.0.0.1 ` +
`or hosts listed by --allow-insecure-connection / ${LLM_ALLOW_INSECURE_CONNECTION_ENV}. ` +
`Use https:// for remote endpoints (got ${parsed.origin})`,
);
}
}
}
View on GitHub (pinned to 52924ef12c)