{"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":"http","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/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/client/oauth.go#L317-L353","documentation":"Wrapped error at oauth.go:334-335 when putOAuthCredential fails to persist the freshly registered client credential (client_id, secret, endpoints, scopes). The registration itself succeeded but local storage (keystore backing oauthCredential) rejected the write.","triggerScenarios":"putOAuthCredential returns a non-nil error immediately after a successful RegisterClient and the TokenAuthMethod validation passed. Subsequent calls will re-attempt registration because nothing was saved.","commonSituations":"Disk full or permission denied on the keystore file; workspace data directory not writable; keystore JSON corruption that fails to serialize; antivirus/file-lock on Windows locking the credential file.","solutions":["Check the wrapped error (file system errno) and free space / fix permissions on the kernel data directory.","Ensure no other SiYuan process holds the workspace lock (single-instance requirement).","Retry the authorization once the storage issue is resolved; the AS registration is still valid until it expires, but SiYuan must re-register because the save failed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err = putOAuthCredential(registrationCredential); err != nil {\n    // Error 327: registration succeeded locally but persistence failed.\n    logging.LogErrorf(\"mcp oauth: persist registration failed: %s\", err)\n    return fmt.Errorf(\"save OAuth client registration: %w\", err)\n}","preventionTips":["Keep the kernel data directory writable and with adequate free space.","Run a single SiYuan instance per workspace to avoid keystore lock contention.","Monitor for filesystem errors in logs to catch persistent storage degradation early."],"tags":["oauth","mcp","storage","persistence","keystore","filesystem"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}