{"record":{"id":"19313244a1acf77c","repo":"can1357/oh-my-pi","slug":"invalid-gitlab-redirect-uri-raw","errorCode":null,"errorMessage":"Invalid GITLAB_REDIRECT_URI: ${raw}","messagePattern":"Invalid GITLAB_REDIRECT_URI: (.+?)","errorType":"exception","errorClass":"AIError.OAuthError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/registry/oauth/gitlab-duo.ts","lineNumber":63,"sourceCode":" * so the browser callback lands on us. HTTPS loopback URIs are rejected because\n * the local callback server is plaintext HTTP. Non-loopback URIs bind a random\n * local port — only the paste-code path can complete in that case.\n */\nfunction resolveCallbackOptions(): OAuthCallbackFlowOptions {\n\tconst raw = process.env.GITLAB_REDIRECT_URI?.trim();\n\tif (!raw) {\n\t\treturn {\n\t\t\tpreferredPort: DEFAULT_CALLBACK_PORT,\n\t\t\tcallbackPath: DEFAULT_CALLBACK_PATH,\n\t\t\tcallbackHostname: DEFAULT_CALLBACK_HOSTNAME,\n\t\t};\n\t}\n\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\tthrow new AIError.OAuthError(`Invalid GITLAB_REDIRECT_URI: ${raw}`, {\n\t\t\tkind: \"configuration\",\n\t\t\tprovider: \"gitlab-duo\",\n\t\t});\n\t}\n\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\tthrow new AIError.OAuthError(`GITLAB_REDIRECT_URI must use http:// or https://, got: ${raw}`, {\n\t\t\tkind: \"configuration\",\n\t\t\tprovider: \"gitlab-duo\",\n\t\t});\n\t}\n\n\tconst isLoopback = parsed.hostname === \"localhost\" || parsed.hostname === \"127.0.0.1\" || parsed.hostname === \"[::1]\";\n\tif (isLoopback && parsed.protocol !== \"http:\") {\n\t\tthrow new AIError.OAuthError(`GITLAB_REDIRECT_URI loopback callbacks must use http://, got: ${raw}`, {\n\t\t\tkind: \"configuration\",\n\t\t\tprovider: \"gitlab-duo\",\n\t\t});\n\t}","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/registry/oauth/gitlab-duo.ts#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix GITLAB_REDIRECT_URI to a full absolute URL including scheme, e.g. http://localhost:8080/callback.","Match it exactly against the redirect URI registered on your GitLab OAuth application (strict matching is enforced).","Unset GITLAB_REDIRECT_URI entirely to fall back to the default http://localhost:8080/callback flow.","If you only need GitLab access, skip OAuth by setting GITLAB_TOKEN to a Personal Access Token."],"exampleFix":"// before (.env)\nGITLAB_REDIRECT_URI=localhost:8080/callback\n\n// after (.env)\nGITLAB_REDIRECT_URI=http://localhost:8080/callback","handlingStrategy":"validation","validationCode":"const raw = process.env.GITLAB_REDIRECT_URI?.trim();\nif (raw) {\n  try {\n    new URL(raw); // throws exactly like the library will\n  } catch {\n    throw new Error(`GITLAB_REDIRECT_URI is not a valid absolute URL: ${raw}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await loginGitLabDuo(callbacks);\n} catch (err) {\n  if (err?.kind === \"configuration\" && String(err.message).includes(\"Invalid GITLAB_REDIRECT_URI\")) {\n    delete process.env.GITLAB_REDIRECT_URI; // fall back to default localhost:8080/callback\n    await loginGitLabDuo(callbacks);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always include the scheme in GITLAB_REDIRECT_URI: http:// or https://.","Validate env vars with a quick `new URL()` sanity check in startup scripts.","Keep .env values free of stray quotes/spaces that break URL parsing.","Prefer leaving GITLAB_REDIRECT_URI unset and using the default http://localhost:8080/callback."],"tags":["oauth","gitlab","configuration","env-var"],"backgroundTag":"invalid-redirect-uri","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}