{"record":{"id":"8a6a4d82c0c1a37c","repo":"router-for-me/CLIProxyAPI","slug":"post-auth-hook-failed-w","errorCode":null,"errorMessage":"post-auth hook failed: %w","messagePattern":"post-auth hook failed: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/api/handlers/management/auth_files_fields.go","lineNumber":746,"sourceCode":"\t}\n\n\tif len(existingMap) > 0 {\n\t\tcoreauth.MergeExistingAuthMetadata(record, existingMap)\n\t}\n}\n\nfunc (h *Handler) saveTokenRecord(ctx context.Context, record *coreauth.Auth) (string, error) {\n\tif record == nil {\n\t\treturn \"\", fmt.Errorf(\"token record is nil\")\n\t}\n\th.mergeExistingAuthFileMetadata(record)\n\tstore := h.tokenStoreWithBaseDir()\n\tif store == nil {\n\t\treturn \"\", fmt.Errorf(\"token store unavailable\")\n\t}\n\tif h.postAuthHook != nil {\n\t\tif err := h.postAuthHook(ctx, record); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"post-auth hook failed: %w\", err)\n\t\t}\n\t}\n\tsavedPath, errSave := store.Save(ctx, record)\n\tif errSave != nil {\n\t\treturn savedPath, errSave\n\t}\n\tif h.postAuthPersistHook != nil {\n\t\tif errHook := h.postAuthPersistHook(ctx, record); errHook != nil {\n\t\t\treturn savedPath, fmt.Errorf(\"post-auth persist hook failed: %w\", errHook)\n\t\t}\n\t}\n\treturn savedPath, nil\n}\n","sourceCodeStart":728,"sourceCodeEnd":760,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/auth_files_fields.go#L728-L760","documentation":"The pre-save hook h.postAuthHook, run by saveTokenRecord before store.Save, returned an error, so the credential record was not persisted. This hook is wired by the host application/SDK to perform side effects such as config sync or notification before a token lands on disk; its failure is treated as fatal for the save.","triggerScenarios":"Completing an OAuth login or saving an auth record when the registered post-auth hook fails — e.g. a hook that writes to config.yaml hitting a permissions error, or a hook validating provider state and rejecting the record.","commonSituations":"Custom embedders adding hooks that touch the filesystem or external services; config dir read-only in containers; hook logic version-skew after upgrading the SDK.","solutions":["Inspect the wrapped error — it comes from the hook implementation, not from storage","Fix whatever the hook needs (writable config path, reachable dependency) based on its own error text","If the hook's failures should be non-fatal, change it to return nil on soft errors or make it skippable by configuration","Retry the save; nothing was persisted, so the operation is safe to repeat"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := h.saveTokenRecord(ctx, record); err != nil {\n    if strings.HasPrefix(err.Error(), \"post-auth hook failed\") {\n        // nothing persisted; fix the hook dependency, then retry the save safely\n    }\n}","preventionTips":["Keep post-auth hooks idempotent and dependency-light","Log hook errors with enough context to identify the failing side effect","Make optional hook failures configurable to skip instead of abort"],"tags":["hooks","sdk","auth","config"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}