{"record":{"id":"b83971e5ec39be75","repo":"Tencent/WeKnora","slug":"token-exchange-failed-w","errorCode":null,"errorMessage":"token exchange failed: %w","messagePattern":"token exchange failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/oauth_manager.go","lineNumber":216,"sourceCode":"\n\tservice, err := m.serviceRepo.GetByID(ctx, st.TenantID, st.ServiceID)\n\tif err != nil {\n\t\treturn frontendRedirect, serviceID, fmt.Errorf(\"failed to load MCP service: %w\", err)\n\t}\n\tif service == nil {\n\t\treturn frontendRedirect, serviceID, fmt.Errorf(\"MCP service not found\")\n\t}\n\n\th, err := m.newHandler(ctx, service, st.TenantID, principal, st.RedirectURI)\n\tif err != nil {\n\t\treturn frontendRedirect, serviceID, err\n\t}\n\t// Re-prime the expected state so the library's CSRF check passes after\n\t// reconstructing the handler in this separate request.\n\th.SetExpectedState(state)\n\n\tif err := h.ProcessAuthorizationResponse(ctx, code, state, st.CodeVerifier); err != nil {\n\t\treturn frontendRedirect, serviceID, fmt.Errorf(\"token exchange failed: %w\", err)\n\t}\n\tif err := m.states.CompleteAttempt(ctx, state); err != nil {\n\t\treturn frontendRedirect, serviceID, fmt.Errorf(\"failed to record authorization completion: %w\", err)\n\t}\n\t// ProcessAuthorizationResponse persists the token via the TokenStore.\n\tlogger.GetLogger(ctx).Infof(\n\t\t\"MCP OAuth authorized: service=%s principal=%s\", st.ServiceID, principal.StorageID(),\n\t)\n\treturn frontendRedirect, serviceID, nil\n}\n\n// IsAuthorizationAttemptComplete reports whether this exact authorization\n// attempt completed for the requested principal and service. A pre-existing\n// token must never satisfy a newly opened OAuth popup.\nfunc (m *OAuthManager) IsAuthorizationAttemptComplete(\n\tctx context.Context,\n\ttenantID uint64,\n\tprincipal types.Principal,","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/oauth_manager.go#L198-L234","documentation":"Returned by CompleteAuthorization when h.ProcessAuthorizationResponse fails to exchange the authorization code for tokens (invalid or expired code, PKCE mismatch, provider rejection, or network failure to the token endpoint). The user's authorization does not complete and must be restarted.","triggerScenarios":"Thrown at internal/mcp/oauth_manager.go:216 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the wrapped error from the token endpoint","Auth codes are single-use and short-lived — restart the flow with a fresh code","Verify client ID/secret, redirect URI, and PKCE verifier consistency","Check connectivity to the OAuth provider's token endpoint"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}