alibaba/open-code-review · error

resolve home dir: %w

Error message

resolve home dir: %w

What it means

SessionsDir computes the per-repo session directory under ~/.opencodereview. It calls os.UserHomeDir, and if that fails (home directory cannot be determined) the error is wrapped as 'resolve home dir: ...'. No directory is created by this function.

Source

Thrown at internal/session/list.go:101

	FilesReviewed   []string        `json:"files_reviewed"`
	DurationSeconds float64         `json:"duration_seconds"`
	LLMFailures     int64           `json:"llm_failures"`
	RunManifest     *RunManifest    `json:"run_manifest"`
	SchemaVersion   string          `json:"schema_version"`
	RunID           string          `json:"run_id"`
	ParentRunID     string          `json:"parent_run_id"`
	SourceProvider  string          `json:"source_provider"`
	SourceModel     string          `json:"source_model"`
	TargetProvider  string          `json:"target_provider"`
	TargetModel     string          `json:"target_model"`
}

// SessionsDir returns the on-disk directory that holds JSONL session files
// for a given repository. It does not create the directory.
func SessionsDir(repoDir string) (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("resolve home dir: %w", err)
	}
	return filepath.Join(home, ".opencodereview", sessionSubDir, encodeRepoPath(repoDir)), nil
}

// ListSessions enumerates all persisted sessions for the given repository
// directory, sorted by StartTime descending (most recent first). Missing
// directories return an empty slice with no error.
func ListSessions(repoDir string) ([]Summary, error) {
	dir, err := SessionsDir(repoDir)
	if err != nil {
		return nil, err
	}
	entries, err := os.ReadDir(dir)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("read sessions dir %q: %w", dir, err)

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Export HOME (Unix) or USERPROFILE (Windows) to a writable directory before running the command.
  2. If using sudo, use `sudo -E` or set HOME explicitly.
  3. In containers, set ENV HOME=/root (or the app user's home) in the image.
  4. Fix the wrapped OS error if HOME is set but invalid (e.g. home listed in /etc/passwd does not exist).

Example fix

// before
ocr session list
// error: resolve home dir: $HOME is not defined
// after
export HOME=/home/dev
ocr session list
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("HOME") == "" && runtime.GOOS != "windows" {
    return fmt.Errorf("HOME must be set before using session features")
}
if _, err := os.UserHomeDir(); err != nil {
    return fmt.Errorf("home dir unresolvable: %w", err)
}

Try / catch

dir, err := session.SessionsDir(repoDir)
if err != nil {
    if strings.Contains(err.Error(), "resolve home dir") {
        os.Setenv("HOME", "/tmp") // or prompt user / fail fast
        return session.SessionsDir(repoDir)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SessionsDir (directly or via ListSessions/countSessionFiles) when os.UserHomeDir returns an error — $HOME is empty on Unix or the USERPROFILE lookup fails on Windows.

Common situations: Running in CI containers or systemd services with HOME unset; sudo/su environments dropping HOME; Docker images running as non-root user without HOME configured.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/332430150b5e336c. Report an issue: GitHub.