can1357/oh-my-pi · error · SearchProviderError

GOOGLE_GEMINI_BASE_URL must use HTTP or HTTPS

Error message

GOOGLE_GEMINI_BASE_URL must use HTTP or HTTPS

What it means

resolveGeminiDeveloperEndpoint() throws this when GOOGLE_GEMINI_BASE_URL parses as a URL but its protocol is neither https: nor http:. The Gemini developer endpoint must be fetched over HTTP(S); other schemes (ftp:, ws:, file:, etc.) are rejected with a 400 SearchProviderError before any request is sent.

Source

Thrown at packages/coding-agent/src/web/search/providers/gemini.ts:59

}

interface GeminiDeveloperEndpoint {
	url: string;
	authProvider: typeof DEVELOPER_API_PROVIDER | typeof CLOUDFLARE_GATEWAY_PROVIDER;
	isCloudflareGateway: boolean;
}

function resolveGeminiDeveloperEndpoint(): GeminiDeveloperEndpoint {
	const configuredHost = Bun.env.GOOGLE_GEMINI_BASE_URL?.trim().replace(/\/+$/, "");
	const host = configuredHost || DEFAULT_DEVELOPER_API_HOST;
	let parsed: URL;
	try {
		parsed = new URL(host);
	} catch {
		throw new SearchProviderError("gemini", "GOOGLE_GEMINI_BASE_URL must be a valid absolute URL", 400);
	}
	if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
		throw new SearchProviderError("gemini", "GOOGLE_GEMINI_BASE_URL must use HTTP or HTTPS", 400);
	}
	const isCloudflareGateway = parsed.hostname === "gateway.ai.cloudflare.com";
	return {
		url: `${host}/${DEVELOPER_API_VERSION}`,
		authProvider: isCloudflareGateway ? CLOUDFLARE_GATEWAY_PROVIDER : DEVELOPER_API_PROVIDER,
		isCloudflareGateway,
	};
}

const GEMINI_PROVIDERS = ["google-gemini-cli", "google-antigravity"] as const;
type GeminiProviderId = (typeof GEMINI_PROVIDERS)[number];

interface GeminiToolParams {
	google_search?: Record<string, unknown>;
	code_execution?: Record<string, unknown>;
	url_context?: Record<string, unknown>;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Change the value to start with https:// (or http:// only for local testing/proxies that require it)
  2. Print the parsed protocol (`new URL(value).protocol`) to see what the parser derives from your value
  3. Unset GOOGLE_GEMINI_BASE_URL to use the default HTTPS developer API host

Example fix

// before
GOOGLE_GEMINI_BASE_URL=wss://gemini-proxy.internal
// after
GOOGLE_GEMINI_BASE_URL=https://gemini-proxy.internal
Defensive patterns

Strategy: validation

Validate before calling

const v = Bun.env.GOOGLE_GEMINI_BASE_URL?.trim();
if (v) {
  const proto = new URL(v).protocol;
  if (proto !== "https:" && proto !== "http:") {
    throw new Error(`GOOGLE_GEMINI_BASE_URL must use http/https, got '${proto}'`);
  }
}

Type guard

function isHttpLikeBase(value: string | undefined): boolean {
  if (!value) return true;
  try {
    const p = new URL(value.trim()).protocol;
    return p === "http:" || p === "https:";
  } catch { return false; }
}

Try / catch

try {
  results = await searchGemini(query);
} catch (err) {
  if (err instanceof SearchProviderError && err.message.includes("must use HTTP or HTTPS")) {
    logger.error("GOOGLE_GEMINI_BASE_URL scheme rejected — use https://", { cause: err.message });
    results = await fallbackSearch(query);
  } else throw err;
}

Prevention

When it happens

Trigger: GOOGLE_GEMINI_BASE_URL set with a non-HTTP scheme — e.g. 'wss://gateway.example.com', 'file:///etc/gemini', or a typo like 'https:/host' that the URL parser resolves to a different scheme. Reached via endpoint() or isAvailable().

Common situations: Pointing the base URL at a websocket or unix-file endpoint, scheme typos, or URL values mangled by shell escaping that shift the colon placement.

Related errors


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