{"record":{"id":"b5e8e223841f9cf2","repo":"different-ai/openwork","slug":"an-enterprise-mcp-oauth-redirect-uri-cannot-contai","errorCode":null,"errorMessage":"An enterprise MCP OAuth redirect URI cannot contain credentials or a fragment.","messagePattern":"An enterprise MCP OAuth redirect URI cannot contain credentials or a fragment\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/enterprise-mcp-client/src/enterprise-mcp-client.ts","lineNumber":121,"sourceCode":"  const url = new URL(parsed.serverUrl)\n  if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n    throw new Error(\"An enterprise MCP server URL must use HTTP or HTTPS.\")\n  }\n  if (url.username || url.password) {\n    throw new Error(\"An enterprise MCP server URL cannot contain embedded credentials.\")\n  }\n  if (url.hash) throw new Error(\"An enterprise MCP server URL cannot contain a fragment.\")\n  return url\n}\n\nfunction validateRedirectUri(redirectUri: string): string {\n  const parsed = redirectUriSchema.parse(redirectUri)\n  const url = new URL(parsed)\n  if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n    throw new Error(\"An enterprise MCP OAuth redirect URI must use HTTP or HTTPS.\")\n  }\n  if (url.username || url.password || url.hash) {\n    throw new Error(\"An enterprise MCP OAuth redirect URI cannot contain credentials or a fragment.\")\n  }\n  return parsed\n}\n\nfunction configurationValue<T>(parse: () => T): T {\n  try {\n    return parse()\n  } catch (error) {\n    throw new EnterpriseMcpClientError({\n      operationPhase: \"configuration\",\n      requestPhase: null,\n      cause: error,\n    })\n  }\n}\n\nasync function closeWithinDeadline(close: () => Promise<void>, timeoutMs: number): Promise<void> {\n  let timer: ReturnType<typeof setTimeout> | undefined","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/enterprise-mcp-client/src/enterprise-mcp-client.ts#L103-L139","documentation":"validateRedirectUri in packages/enterprise-mcp-client/src/enterprise-mcp-client.ts throws when the redirect URI contains embedded userinfo credentials (username/password) or a fragment. Both are invalid for OAuth redirect URIs per RFC 9700 (fragments never reach the server; credentials in URLs leak secrets) and would break exact-match registration at the authorization server.","triggerScenarios":"Passing a redirect URI like \"https://user:pass@example.com/cb\" or \"https://example.com/cb#frag\" to the client's redirect URI configuration.","commonSituations":"Reusing a URL copied from a browser (with an anchor) as the redirect; template config values like https://USER:PASS@host/cb that were never substituted out; confusion between the server URL rules and redirect URI rules.","solutions":["Remove any user:pass@ userinfo and #fragment from the redirect URI.","Register a clean https:// (or http://127.0.0.1 loopback) callback with the authorization server and use exactly that string.","Validate the redirect URI shape before constructing the client."],"exampleFix":"// before\nredirectUri: \"https://admin:secret@mcp.example.com/callback#oauth\"\n\n// after\nredirectUri: \"https://mcp.example.com/callback\"","handlingStrategy":"validation","validationCode":"function assertCleanRedirectUri(redirectUri: string) {\n  const u = new URL(redirectUri)\n  if (u.username || u.password || u.hash) {\n    throw new Error(\"redirectUri must not contain credentials or a fragment\")\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep redirect URIs to scheme://host/path with no userinfo and no '#'","Verify the registered callback in the authorization-server admin console matches byte-for-byte","Avoid copying URLs from browsers (they often include anchors)"],"tags":["oauth","redirect-uri","security","validation"],"backgroundTag":"invalid-redirect-uri","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}