{"record":{"id":"3512a79dc8c2fb28","repo":"siyuan-note/siyuan","slug":"save-oauth-client-registration-w","errorCode":null,"errorMessage":"save OAuth client registration: %w","messagePattern":"save OAuth client registration: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/client/oauth.go","lineNumber":335,"sourceCode":"\t\t\tClientSecret:        registration.ClientSecret,\n\t\t\tClientSecretExpiry:  registration.ClientSecretExpiresAt,\n\t\t\tTokenEndpoint:       asm.TokenEndpoint,\n\t\t\tRevocationEndpoint:  asm.RevocationEndpoint,\n\t\t\tTokenAuthMethod:     registration.TokenEndpointAuthMethod,\n\t\t\tScopes:              scopes,\n\t\t}\n\t\tif registrationCredential.TokenAuthMethod == \"\" {\n\t\t\tif registration.ClientSecret == \"\" {\n\t\t\t\tregistrationCredential.TokenAuthMethod = \"none\"\n\t\t\t} else {\n\t\t\t\tregistrationCredential.TokenAuthMethod = \"client_secret_basic\"\n\t\t\t}\n\t\t}\n\t\tif !isSupportedTokenAuthMethod(registrationCredential.TokenAuthMethod) {\n\t\t\treturn fmt.Errorf(\"OAuth client registration returned an unsupported token endpoint authentication method\")\n\t\t}\n\t\tif err = putOAuthCredential(registrationCredential); err != nil {\n\t\t\treturn fmt.Errorf(\"save OAuth client registration: %w\", err)\n\t\t}\n\t}\n\n\tauthMethod := registrationCredential.TokenAuthMethod\n\tif authMethod == \"\" {\n\t\tif registrationCredential.ClientSecret == \"\" {\n\t\t\tauthMethod = \"none\"\n\t\t} else {\n\t\t\tauthMethod = \"client_secret_basic\"\n\t\t}\n\t}\n\tconfig := &oauth2.Config{\n\t\tClientID:     registrationCredential.ClientID,\n\t\tClientSecret: registrationCredential.ClientSecret,\n\t\tRedirectURL:  callbackURL,\n\t\tScopes:       scopes,\n\t\tEndpoint: oauth2.Endpoint{\n\t\t\tAuthURL:   asm.AuthorizationEndpoint,","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/mcp/client/oauth.go#L317-L353","documentation":"After a successful dynamic client registration, the credential (client id/secret, endpoints, scopes) is persisted via putOAuthCredential. This error wraps any storage failure encountered while saving that registration, so the authorization flow cannot proceed to the browser redirect step. The %w wraps the underlying error from the credential store.","triggerScenarios":"Authorize() completes RegisterClient, the returned TokenAuthMethod is supported, but putOAuthCredential(registrationCredential) returns a non-nil error while persisting the new registration.","commonSituations":"Disk full or read-only data directory; workspace data corruption; concurrent writes to the credential store; permission problems on the SiYuan workspace folder.","solutions":["Check the wrapped error (%w) to identify the storage failure (disk full, permissions, corruption)","Verify the SiYuan workspace data directory is writable and has free space","Restart the kernel to clear any transient store locks, then retry authorization","If the store is corrupted, restore the workspace from backup or repair the credential storage before retrying"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Ensure the workspace data directory is writable before starting OAuth\nif info, err := os.Stat(workspaceDir); err != nil || info.Mode().Perm()&0200 == 0 {\n    return fmt.Errorf(\"workspace dir not writable\")\n}","typeGuard":null,"tryCatchPattern":"if err := h.Authorize(ctx, true); err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) {\n        // handle storage failure: fix disk/permissions then retry\n    }\n}","preventionTips":["Keep the SiYuan workspace on a writable volume with free disk space","Watch disk-full and permission errors in kernel logs","Avoid moving or locking the workspace directory during an OAuth flow"],"tags":["oauth","mcp","persistence","storage"],"backgroundTag":"file-write-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}