can1357/oh-my-pi · error · AIError.OAuthError

Invalid GITLAB_REDIRECT_URI: ${raw}

Error message

Invalid GITLAB_REDIRECT_URI: ${raw}

What it means

resolveCallbackOptions reads GITLAB_REDIRECT_URI and parses it with new URL(). If the value cannot be parsed as a URL at all, this configuration OAuthError is thrown with the raw value echoed back. It guards the GitLab Duo OAuth login flow against an unparseable redirect URI before any network calls are made.

Source

Thrown at packages/ai/src/registry/oauth/gitlab-duo.ts:63

 * so the browser callback lands on us. HTTPS loopback URIs are rejected because
 * the local callback server is plaintext HTTP. Non-loopback URIs bind a random
 * local port — only the paste-code path can complete in that case.
 */
function resolveCallbackOptions(): OAuthCallbackFlowOptions {
	const raw = process.env.GITLAB_REDIRECT_URI?.trim();
	if (!raw) {
		return {
			preferredPort: DEFAULT_CALLBACK_PORT,
			callbackPath: DEFAULT_CALLBACK_PATH,
			callbackHostname: DEFAULT_CALLBACK_HOSTNAME,
		};
	}

	let parsed: URL;
	try {
		parsed = new URL(raw);
	} catch {
		throw new AIError.OAuthError(`Invalid GITLAB_REDIRECT_URI: ${raw}`, {
			kind: "configuration",
			provider: "gitlab-duo",
		});
	}
	if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
		throw new AIError.OAuthError(`GITLAB_REDIRECT_URI must use http:// or https://, got: ${raw}`, {
			kind: "configuration",
			provider: "gitlab-duo",
		});
	}

	const isLoopback = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]";
	if (isLoopback && parsed.protocol !== "http:") {
		throw new AIError.OAuthError(`GITLAB_REDIRECT_URI loopback callbacks must use http://, got: ${raw}`, {
			kind: "configuration",
			provider: "gitlab-duo",
		});
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Fix GITLAB_REDIRECT_URI to a full absolute URL including scheme, e.g. http://localhost:8080/callback.
  2. Match it exactly against the redirect URI registered on your GitLab OAuth application (strict matching is enforced).
  3. Unset GITLAB_REDIRECT_URI entirely to fall back to the default http://localhost:8080/callback flow.
  4. If you only need GitLab access, skip OAuth by setting GITLAB_TOKEN to a Personal Access Token.

Example fix

// before (.env)
GITLAB_REDIRECT_URI=localhost:8080/callback

// after (.env)
GITLAB_REDIRECT_URI=http://localhost:8080/callback
Defensive patterns

Strategy: validation

Validate before calling

const raw = process.env.GITLAB_REDIRECT_URI?.trim();
if (raw) {
  try {
    new URL(raw); // throws exactly like the library will
  } catch {
    throw new Error(`GITLAB_REDIRECT_URI is not a valid absolute URL: ${raw}`);
  }
}

Try / catch

try {
  await loginGitLabDuo(callbacks);
} catch (err) {
  if (err?.kind === "configuration" && String(err.message).includes("Invalid GITLAB_REDIRECT_URI")) {
    delete process.env.GITLAB_REDIRECT_URI; // fall back to default localhost:8080/callback
    await loginGitLabDuo(callbacks);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: GITLAB_REDIRECT_URI is set (non-empty after trim) but is not a valid absolute URL — e.g. 'localhost:8080/callback' (no scheme), 'http:/localhost:8080' (malformed), 'just-a-string', or a value containing stray spaces/quotes from a .env file.

Common situations: Missing scheme in the env var (people write localhost:8080/callback); copying a relative path from GitLab's app registration; shell quoting mangling the value; typo like 'http//:'; setting it in package.json scripts without escaping.

Related errors


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