{"record":{"id":"14f9b6eeb0259733","repo":"alibaba/open-code-review","slug":"resolve-home-dir-w-14f9b6","errorCode":null,"errorMessage":"resolve home dir: %w","messagePattern":"resolve home dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/session/resume.go","lineNumber":87,"sourceCode":"\tScanPaths       *[]string          `json:\"scanPaths\"`\n\tFilePath        string             `json:\"filePath\"`\n\tOldPath         string             `json:\"oldPath\"`\n\tNewPath         string             `json:\"newPath\"`\n\tFingerprint     string             `json:\"fingerprint\"`\n\tSourceSessionID string             `json:\"sourceSessionId\"`\n\tError           string             `json:\"error\"`\n\tComments        []model.LlmComment `json:\"comments\"`\n\tRunManifest     *RunManifest       `json:\"run_manifest\"`\n}\n\n// SessionFilePath returns the JSONL path for a persisted session.\nfunc SessionFilePath(repoDir, sessionID string) (string, error) {\n\tif sessionID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"session id is required\")\n\t}\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"resolve home dir: %w\", err)\n\t}\n\treturn filepath.Join(home, \".opencodereview\", sessionSubDir, encodeRepoPath(repoDir), sessionID+\".jsonl\"), nil\n}\n\n// LoadResumeState replays a previous session JSONL into a fingerprint index. A\n// record that cannot be parsed fails the load: with nothing to arbitrate coverage,\n// a dropped line is indistinguishable from a checkpoint that was never written,\n// and the pair it may have belonged to — a review_item_failed retracting an\n// earlier done record — cannot be reconstructed from the rest of the file.\nfunc LoadResumeState(repoDir, sessionID string) (*ResumeState, error) {\n\treturn loadResumeState(repoDir, sessionID, false)\n}\n\n// LoadReviewResumeState replays a review session, dropping records it cannot\n// parse. Review reuse is gated on the parent manifest rather than on these lines\n// (see ReusableItem), so an unreadable checkpoint just means its file is reviewed\n// again — which is what a corrupted checkpoint is supposed to do. Failing the\n// whole load instead would turn one bad line into the loss of every other file's","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/session/resume.go#L69-L105","documentation":"SessionFilePath resolves the user's home directory to construct the absolute JSONL path; a failure from os.UserHomeDir() is wrapped as 'resolve home dir'. Without a home directory the library cannot know where sessions are stored, so the lookup fails. This mirrors the same failure in persist.go's writer open path.","triggerScenarios":"SessionFilePath (via LoadComments/LoadSummary/LoadDetail/loadResumeState) calls os.UserHomeDir() and it errors: HOME unset in the process environment and no passwd entry for the current user.","commonSituations":"Cron/systemd/CI environments without HOME; Docker containers running as a bare uid; su/sudo configurations stripping the environment.","solutions":["Set HOME to the directory holding ~/.opencodereview (export HOME=/root or the user's real home) before running the tool","Run as a user with a valid passwd entry and home directory","In Docker, add ENV HOME=/root or pass -e HOME=...","Confirm the session files exist under $HOME/.opencodereview/<sessions>/<encoded-repo>/ once HOME is correct"],"exampleFix":"// before (systemd unit)\nExecStart=/usr/local/bin/ocr resume\n// after\nEnvironment=HOME=/root\nExecStart=/usr/local/bin/ocr resume","handlingStrategy":"validation","validationCode":"if os.Getenv(\"HOME\") == \"\" {\n    if _, err := os.UserHomeDir(); err != nil {\n        return fmt.Errorf(\"HOME not resolvable; sessions cannot be located: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"path, err := session.SessionFilePath(repoDir, sessionID)\nif err != nil {\n    if strings.Contains(err.Error(), \"resolve home dir\") {\n        log.Fatalf(\"set HOME to the directory containing ~/.opencodereview: %v\", err)\n    }\n}","preventionTips":["Export HOME in headless environments (cron, systemd, Docker)","Run loaders as the same user that created the sessions","Verify $HOME/.opencodereview exists before attempting resume"],"tags":["filesystem","environment","home-directory"],"backgroundTag":"home-dir-not-set","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}