{"record":{"id":"7f1903a59c760551","repo":"router-for-me/CLIProxyAPI","slug":"failed-to-write-auth-file-w","errorCode":null,"errorMessage":"failed to write auth file: %w","messagePattern":"failed to write auth file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/auth_callbacks.go","lineNumber":297,"sourceCode":"}\n\nfunc (h *Host) saveAuthFile(ctx context.Context, name string, data []byte) (string, error) {\n\tauthDir := h.resolvedAuthDir()\n\tif authDir == \"\" {\n\t\treturn \"\", fmt.Errorf(\"auth directory is unavailable\")\n\t}\n\tdst := filepath.Join(authDir, filepath.Base(name))\n\tif !filepath.IsAbs(dst) {\n\t\tif abs, errAbs := filepath.Abs(dst); errAbs == nil {\n\t\t\tdst = abs\n\t\t}\n\t}\n\tauth, errBuild := h.buildAuthFromFileData(dst, data)\n\tif errBuild != nil {\n\t\treturn \"\", errBuild\n\t}\n\tif errWrite := os.WriteFile(dst, data, 0o600); errWrite != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to write auth file: %w\", errWrite)\n\t}\n\tif errUpsert := h.upsertAuthRecord(ctx, auth); errUpsert != nil {\n\t\treturn \"\", errUpsert\n\t}\n\treturn dst, nil\n}\n\nfunc (h *Host) buildAuthFromFileData(path string, data []byte) (*coreauth.Auth, error) {\n\tif strings.TrimSpace(path) == \"\" {\n\t\treturn nil, fmt.Errorf(\"auth path is empty\")\n\t}\n\tif data == nil {\n\t\tvar errRead error\n\t\tdata, errRead = os.ReadFile(path)\n\t\tif errRead != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read auth file: %w\", errRead)\n\t\t}\n\t}","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/auth_callbacks.go#L279-L315","documentation":"Wrapped error from os.WriteFile in Host.saveAuthFile with mode 0600 when persisting the auth file fails. The %w preserves the underlying PathError; typical causes are missing directory, permission denied, or disk full.","triggerScenarios":"The auth directory was deleted between resolution and write; process user lacks write permission on auths/; disk quota exhausted; read-only filesystem (common in mis-mounted containers).","commonSituations":"Container image with auths/ not writable or not volume-mounted; SELinux/AppArmor denying writes; deploying as non-root for the first time against root-owned directories.","solutions":["Inspect the wrapped *fs.PathError for errno (EACCES, ENOSPC, EROFS)","Create the auth directory and chown/chmod it for the process user","Mount a writable persistent volume at the auth path in container deployments"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-flight writability check:\nprobe := filepath.Join(authDir, \".write-probe\")\nif err := os.WriteFile(probe, nil, 0o600); err != nil {\n    // surface permission/disk issue before the real save\n} else { os.Remove(probe) }","typeGuard":null,"tryCatchPattern":"var pathErr *fs.PathError\nif errors.As(err, &pathErr) {\n    // EACCES -> fix perms; ENOSPC -> free space; EROFS -> remount/mount volume\n}","preventionTips":["Mount a writable persistent volume at auths/ in containers","Include a startup check that creates and removes a probe file in the auth dir"],"tags":["go","pluginhost","auth","filesystem","permissions","io"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}