alibaba/open-code-review · error

read sessions dir %q: %w

Error message

read sessions dir %q: %w

What it means

ListSessions reads the per-repo sessions directory and, if os.ReadDir fails with anything other than NotExist (which yields an empty list), wraps it as 'read sessions dir %q: ...'. This means the sessions directory exists but cannot be read, or another OS error occurred.

Source

Thrown at internal/session/list.go:119

		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)
	}
	summaries := make([]Summary, 0, len(entries))
	for _, entry := range entries {
		name := entry.Name()
		if entry.IsDir() || !strings.HasSuffix(name, ".jsonl") {
			continue
		}
		sessionID := strings.TrimSuffix(name, ".jsonl")
		summary, err := loadSummaryFromFile(filepath.Join(dir, name), sessionID, repoDir)
		if err != nil {
			continue
		}
		summaries = append(summaries, *summary)
	}
	sort.Slice(summaries, func(i, j int) bool {
		return summaries[i].StartTime.After(summaries[j].StartTime)
	})
	return summaries, nil

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. ls -la ~/.opencodereview/sessions/ — if the repo path is a file, remove or rename it.
  2. Fix permissions: chown/chmod the sessions directory so the current user can read it.
  3. Check for mount/stale-handle issues if the directory lives on a network filesystem.
  4. Read the wrapped cause (%w) for the exact errno (EACCES, ENOTDIR, etc.).

Example fix

// before
$ ls -la ~/.opencodereview/sessions/
-rw-r--r--  repo-abc123   (file where dir should be)
// after
rm ~/.opencodereview/sessions/repo-abc123
ocr session list
Defensive patterns

Strategy: try-catch

Validate before calling

dir, err := session.SessionsDir(repoDir)
if err != nil {
    return err
}
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s is a file, not a directory", dir)
}

Try / catch

sessions, err := session.ListSessions(repoDir)
if err != nil {
    if strings.Contains(err.Error(), "read sessions dir") {
        // permission/ENOTDIR issue: attempt repair or degrade gracefully
        log.Warnf("cannot read sessions: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling ListSessions (or runSessionList/completeSessionIDs) when the sessions dir exists but is unreadable — or is actually a file, or has permission issues. A missing dir returns (nil, nil) and does NOT produce this error.

Common situations: ~/.opencodereview/sessions/<repo> created as a regular file by accident; ownership changed (different user ran before); permissions tightened by security policy; NFS mount stale.

Related errors


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