{"record":{"id":"8ea5ca3c4f350d12","repo":"alibaba/open-code-review","slug":"create-session-dir-w","errorCode":null,"errorMessage":"create session dir: %w","messagePattern":"create session dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/session/persist.go","lineNumber":111,"sourceCode":"\tvol = strings.ReplaceAll(vol, \":\", \"_\")\n\n\t// Handle edge case where path was only separators or volume name\n\tresult := vol + p\n\tif result == \"\" {\n\t\treturn \"empty\"\n\t}\n\treturn result\n}\n\nfunc (jw *jsonlWriter) open() error {\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"resolve home dir: %w\", err)\n\t}\n\n\tsessionDir := filepath.Join(home, \".opencodereview\", sessionSubDir, encodeRepoPath(jw.repoDir))\n\tif err := os.MkdirAll(sessionDir, 0700); err != nil {\n\t\treturn fmt.Errorf(\"create session dir: %w\", err)\n\t}\n\n\tfilename := filepath.Join(sessionDir, jw.sessionID+\".jsonl\")\n\tf, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open session file: %w\", err)\n\t}\n\n\tjw.file = f\n\tjw.writer = bufio.NewWriter(f)\n\treturn nil\n}\n\nfunc (jw *jsonlWriter) writeRecordLocked(rec map[string]any) {\n\tdata, err := json.Marshal(rec)\n\tif err != nil {\n\t\tfmt.Printf(\"[ocr session] failed to marshal record: %v\\n\", err)\n\t\treturn","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/session/persist.go#L93-L129","documentation":"Thrown when os.MkdirAll fails to create the session directory ~/.opencodereview/<sessions>/<encoded-repo-path> with mode 0700. The writer needs this directory to exist before it can create the JSONL session file. The wrapped error carries the underlying os.PathError.","triggerScenarios":"newJSONLWriter -> open() calls os.MkdirAll on the session dir and it fails: a parent path component is a regular file, or the process lacks write permission on $HOME, or the filesystem is read-only.","commonSituations":"$HOME is read-only or full (disk quota exceeded); ~/.opencodereview exists as a file instead of a directory (created accidentally); NFS/containers with read-only mounts; SELinux/AppArmor denials on $HOME.","solutions":["Check whether ~/.opencodereview exists as a file and remove/rename it so it can be a directory (mkdir -p ~/.opencodereview)","Ensure $HOME is writable by the current user (chmod u+w $HOME, or pick a different HOME)","Check disk space/quota (df -h ~) and free space if the filesystem is full","Inspect the wrapped PathError for the exact failing path and fix permissions (chown/chmod) or mounts"],"exampleFix":"// shell\n# before\nls -la ~/.opencodereview   # regular file -> blocks MkdirAll\n// after\nrm ~/.opencodereview && mkdir -p ~/.opencodereview","handlingStrategy":"validation","validationCode":"home, err := os.UserHomeDir()\nif err == nil {\n    dir := filepath.Join(home, \".opencodereview\")\n    if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {\n        return fmt.Errorf(\"%s exists as a file; remove it\", dir)\n    }\n    if err := os.MkdirAll(dir, 0700); err != nil {\n        return err\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := runOCR(); err != nil {\n    if strings.Contains(err.Error(), \"create session dir\") {\n        log.Fatalf(\"Check that $HOME is writable and ~/.opencodereview is not a file: %v\", err)\n    }\n}","preventionTips":["Verify ~/.opencodereview is a directory with u+rwx permissions before running","Monitor disk space and quota on $HOME","Avoid running the tool on read-only or restrictive SELinux contexts"],"tags":["filesystem","permissions","mkdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}