{"record":{"id":"0919ec0566e6d5ae","repo":"Tencent/WeKnora","slug":"failed-to-persist-authorization-state-w","errorCode":null,"errorMessage":"failed to persist authorization state: %w","messagePattern":"failed to persist authorization state: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/oauth_manager.go","lineNumber":147,"sourceCode":"\t\treturn \"\", \"\", fmt.Errorf(\"failed to generate state: %w\", err)\n\t}\n\n\tauthURL, err := h.GetAuthorizationURL(ctx, state, challenge)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to build authorization URL: %w\", err)\n\t}\n\n\tif err := m.states.Put(ctx, state, OAuthState{\n\t\tTenantID:         tenantID,\n\t\tUserID:           principal.StorageID(),\n\t\tPrincipal:        principal,\n\t\tServiceID:        service.ID,\n\t\tCodeVerifier:     verifier,\n\t\tClientID:         h.GetClientID(),\n\t\tRedirectURI:      redirectURI,\n\t\tFrontendRedirect: frontendRedirect,\n\t}); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to persist authorization state: %w\", err)\n\t}\n\n\treturn authURL, state, nil\n}\n\n// StartAuthorizationForService loads the MCP service by ID and starts the\n// authorization-code flow, returning the URL the user must open. It is a\n// convenience for callers (e.g. IM channels) that only hold a service ID and\n// cannot reach the MCP service lookup directly.\nfunc (m *OAuthManager) StartAuthorizationForService(\n\tctx context.Context,\n\ttenantID uint64,\n\tprincipal types.Principal,\n\tserviceID, redirectURI, frontendRedirect string,\n) (string, error) {\n\tservice, err := m.serviceRepo.GetByID(ctx, tenantID, serviceID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to load MCP service: %w\", err)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/oauth_manager.go#L129-L165","documentation":"Returned by StartAuthorization when m.states.Put fails to persist the OAuthState (tenant, principal, service, PKCE verifier) keyed by the state token. The callback later could not be matched to this flow, so starting authorization is aborted to avoid an unrecoverable half-started flow.","triggerScenarios":"Thrown at internal/mcp/oauth_manager.go:147 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the wrapped error — usually a backend store outage or timeout","Check the OAuth state store's connectivity and TTL configuration","Retry the authorization start once the store recovers"],"exampleFix":null,"handlingStrategy":"retry","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"}