can1357/oh-my-pi · error
Invalid OAuth URLs. Please check: Authorization URL: ${aut
Error message
Invalid OAuth URLs. Please check:
Authorization URL: ${authUrl}
Token URL: ${tokenUrl} What it means
When configuring OAuth for an MCP server via the mcp command, the provided authorization URL and token URL are parsed with the URL constructor. If either fails to parse (malformed scheme, missing host, typos, whitespace garbage), this error is thrown listing both URLs so the user can see which value is bad.
Source
Thrown at packages/coding-agent/src/modes/controllers/mcp-command-controller.ts:858
/**
* External cancellation source: when this signal aborts, the in-flight
* OAuth flow is torn down and {@link MCPOAuthCancelledError} is thrown.
* Wizards (which own focus and absorb Esc themselves) pass their own
* controller here; editor-focused callers rely on the Esc hook
* installed below instead.
*/
abortSignal?: AbortSignal;
},
): Promise<OAuthFlowResult> {
const authStorage = this.ctx.session.modelRegistry.authStorage;
let parsedAuthUrl: URL;
// Validate OAuth URLs
try {
parsedAuthUrl = new URL(authUrl);
new URL(tokenUrl);
} catch (_error) {
throw new Error(
`Invalid OAuth URLs. Please check:\n Authorization URL: ${authUrl}\n Token URL: ${tokenUrl}`,
);
}
const resolvedClientId = clientId.trim() || parsedAuthUrl.searchParams.get("client_id")?.trim() || undefined;
const resolvedClientSecret = clientSecret.trim() || undefined;
const manualInput = this.ctx.oauthManualInput;
let manualInputClaim: { promise: Promise<string>; clear: (reason?: string) => void } | undefined;
const oauthTimeout = new AbortController();
// Esc, external aborts, and a replacement MCP flow route through here;
// the timeout path sets its own reason and leaves this flag false so the
// catch can distinguish cancellation (status) from deadline failure.
let cancellationRequested = false;
const requestCancellation = (reason: string): void => {
cancellationRequested = true;
if (!oauthTimeout.signal.aborted) oauthTimeout.abort(reason);
};View on GitHub (pinned to 9690622007)
Solutions
- Check both URLs printed in the error and ensure each is a full absolute URL including scheme (https://...) and host
- Fix the config entry or re-run the MCP OAuth setup command with corrected URLs
- Test the URLs in a browser or with `new URL(url)` in a script before re-running setup
Example fix
// before authUrl = "auth.example.com/authorize"; // missing scheme // after authUrl = "https://auth.example.com/authorize";
Defensive patterns
Strategy: validation
Validate before calling
function isValidUrl(u: string): boolean {
try { new URL(u); return true; } catch { return false; }
}
if (!isValidUrl(authUrl) || !isValidUrl(tokenUrl)) {
console.error('Both authUrl and tokenUrl must be absolute URLs (https://...)');
return;
} Try / catch
try {
await startMcpOAuth({ authUrl, tokenUrl });
} catch (err) {
if (err instanceof Error && err.message.startsWith('Invalid OAuth URLs')) {
// prompt user to correct config
}
} Prevention
- Always include the https:// scheme when entering OAuth URLs
- Validate URLs with new URL() before saving them to config
- Paste URLs whole — avoid manual edits that drop scheme or host
When it happens
Trigger: Running MCP OAuth setup with an authorization URL or token URL that is not a valid absolute URL — e.g. missing https:// scheme, 'localhost:8080' without scheme, or a truncated paste.
Common situations: Copy-pasting URLs from provider docs and dropping the scheme; hand-editing config files and leaving a placeholder; using a relative path like '/oauth/authorize' instead of a full URL.
Related errors
- this server proxies OAuth through mcp-remote, which caches t
- Invalid server config: ${errors.join("; ")}
- Server "${name}" already exists in ${filePath}
- Server "${name}" not found in ${filePath}
- MCP OAuth credential is missing refresh material
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5db53e8e10202687.
Report an issue: GitHub.