{"record":{"id":"6f3e5f76fc53eddd","repo":"router-for-me/CLIProxyAPI","slug":"invalid-auth-file-w-6f3e5f","errorCode":null,"errorMessage":"invalid auth file: %w","messagePattern":"invalid auth file: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/api/handlers/management/auth_files_fields.go","lineNumber":166,"sourceCode":"\t\t\treturn fmt.Errorf(\"failed to update auth %s: %w\", auth.ID, errUpdate)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc setSourceAuthFileDisabled(path string, disabled bool) error {\n\tpath = strings.TrimSpace(path)\n\tif path == \"\" {\n\t\treturn fmt.Errorf(\"source auth path is empty\")\n\t}\n\tdata, errRead := os.ReadFile(path)\n\tif errRead != nil {\n\t\treturn errRead\n\t}\n\tmetadata := make(map[string]any)\n\tif len(bytes.TrimSpace(data)) > 0 {\n\t\tif errUnmarshal := json.Unmarshal(data, &metadata); errUnmarshal != nil {\n\t\t\treturn fmt.Errorf(\"invalid auth file: %w\", errUnmarshal)\n\t\t}\n\t}\n\tif metadata == nil {\n\t\tmetadata = make(map[string]any)\n\t}\n\tmetadata[\"disabled\"] = disabled\n\traw, errMarshal := json.Marshal(metadata)\n\tif errMarshal != nil {\n\t\treturn fmt.Errorf(\"marshal auth file: %w\", errMarshal)\n\t}\n\tif errWrite := os.WriteFile(path, raw, 0o600); errWrite != nil {\n\t\treturn errWrite\n\t}\n\treturn nil\n}\n\nfunc applyAuthDisabledState(auth *coreauth.Auth, disabled bool) {\n\tif auth == nil {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/auth_files_fields.go#L148-L184","documentation":"While flipping the disabled flag on a plugin source auth file, json.Unmarshal of the existing (non-empty) file into map[string]any failed. Unlike a hard read failure, the file was read fine but its content is not parseable JSON, so the handler refuses to rewrite it rather than destroying the malformed content.","triggerScenarios":"Toggling disabled on a source file that was hand-edited into invalid JSON, truncated by a crash, or written by an external tool in another format; the pre-write parse guard in setSourceAuthFileDisabled catches it before metadata[\"disabled\"] could be merged.","commonSituations":"Manual token refresh edits to plugin source files; files synced from another system with encoding issues (BOM, corrupted escapes); partial writes from a killed process.","solutions":["Run jq . on the file to get the exact syntax error location from the wrapped message","Repair or regenerate the source file (re-run the plugin login/import)","Back up the file first if the token inside is still needed — the operation aborts without modifying it","Retry the toggle after the file parses"],"exampleFix":"// before: auths/source.json contains {\"token\": \"abc\",}\n// after: fix to {\"token\": \"abc\"} then retry the PATCH","handlingStrategy":"validation","validationCode":"data, err := os.ReadFile(path)\nif err == nil && len(bytes.TrimSpace(data)) > 0 && !json.Valid(data) {\n    return fmt.Errorf(\"refusing to patch %s: not valid JSON — repair first\", path)\n}","typeGuard":"func isParsableAuthFile(data []byte) bool {\n    t := bytes.TrimSpace(data)\n    return len(t) == 0 || json.Valid(t)\n}","tryCatchPattern":"if err := setSourceAuthFileDisabled(path, true); err != nil && strings.HasPrefix(err.Error(), \"invalid auth file\") {\n    // abort safely: file untouched; repair then retry\n}","preventionTips":["Never hand-edit plugin source files while toggles may run","Back up before external sync tooling rewrites auth files"],"tags":["json","parsing","auth","filesystem"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}