{"record":{"id":"7d38b59708e83583","repo":"router-for-me/CLIProxyAPI","slug":"failed-to-create-token-file-w","errorCode":null,"errorMessage":"failed to create token file: %w","messagePattern":"failed to create token file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/claude/token.go","lineNumber":91,"sourceCode":"func (ts *ClaudeTokenStorage) SaveTokenToFile(authFilePath string) error {\n\tmisc.LogSavingCredentials(authFilePath)\n\tts.Type = \"claude\"\n\n\t// Create directory structure if it doesn't exist\n\tif err := os.MkdirAll(filepath.Dir(authFilePath), 0700); err != nil {\n\t\treturn fmt.Errorf(\"failed to create directory: %v\", err)\n\t}\n\n\t// Merge metadata using helper\n\tdata, errMerge := misc.MergeMetadata(ts, ts.Metadata)\n\tif errMerge != nil {\n\t\treturn fmt.Errorf(\"failed to merge metadata: %w\", errMerge)\n\t}\n\n\t// Create the token file\n\tf, err := os.Create(authFilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create token file: %w\", err)\n\t}\n\tdefer func() {\n\t\tif errClose := f.Close(); errClose != nil {\n\t\t\tlog.Errorf(\"claude token storage: close token file error: %v\", errClose)\n\t\t}\n\t}()\n\n\t// Encode and write the token data as JSON\n\tif err = json.NewEncoder(f).Encode(data); err != nil {\n\t\treturn fmt.Errorf(\"failed to write token to file: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":73,"sourceCodeEnd":105,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/token.go#L73-L105","documentation":"os.Create on the auth file path failed after the directory was successfully created. The token is not persisted, so a successful OAuth login is lost on restart. The wrapped error distinguishes permission issues from path problems (name too long, is-a-directory, O_RDONLY filesystem).","triggerScenarios":"The directory exists and is writable enough for MkdirAll to succeed, but creating the file itself fails: directory without write permission for the file (execute-only traversal), the target path is itself a directory, read-only mount, or filename constraints exceeded.","commonSituations":"auth-dir with mode that allows mkdir traversal but not file creation; auth file path accidentally set to an existing directory; read-only container filesystems where MkdirAll no-ops on existing dirs but Create fails; path length limits with deeply nested auth-dirs.","solutions":["Check the wrapped error text and fix the specific cause: chmod the directory (needs w+x for the runtime user) or remove the conflicting directory at the file path.","Confirm the auth-dir volume is mounted read-write in containers.","Verify the full resolved path is a file location, not a directory."],"exampleFix":"# before\nchmod 111 auths   # traverse-only: mkdir check passes, file create fails\n\n# after\nchmod 700 auths && chown appuser auths","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(authFilePath); err == nil && info.IsDir() {\n    return errors.New(\"auth file path is a directory\")\n}\nf, err := os.OpenFile(authFilePath, os.O_WRONLY|os.O_CREATE, 0600)\nif err != nil { return fmt.Errorf(\"cannot write auth file: %w\", err) }\nf.Close()","typeGuard":null,"tryCatchPattern":"if err := storage.SaveTokenToFile(path); err != nil && strings.Contains(err.Error(), \"failed to create token file\") {\n    log.Errorf(\"check permissions on %s\", filepath.Dir(path))\n}","preventionTips":["Give the runtime user write+execute on auth-dir (chmod 700).","Startup smoke-test: touch a file in auth-dir before doing any login."],"tags":["claude","storage","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}