alibaba/open-code-review · error

open resume session %q: %w

Error message

open resume session %q: %w

What it means

loadResumeState wraps the os.Open failure when replaying a persisted session JSONL from ~/.opencodereview/<repo>/<sessionID>.jsonl. The library throws it because without the session file there is no checkpoint index to rebuild, so resume cannot proceed. The wrapped os error (usually fs.ErrNotExist) names the real cause.

Source

Thrown at internal/session/resume.go:118

// LoadReviewResumeState replays a review session, dropping records it cannot
// parse. Review reuse is gated on the parent manifest rather than on these lines
// (see ReusableItem), so an unreadable checkpoint just means its file is reviewed
// again — which is what a corrupted checkpoint is supposed to do. Failing the
// whole load instead would turn one bad line into the loss of every other file's
// checkpoint.
func LoadReviewResumeState(repoDir, sessionID string) (*ResumeState, error) {
	return loadResumeState(repoDir, sessionID, true)
}

func loadResumeState(repoDir, sessionID string, skipUnparseable bool) (*ResumeState, error) {
	path, err := SessionFilePath(repoDir, sessionID)
	if err != nil {
		return nil, err
	}
	f, err := os.Open(path)
	if err != nil {
		return nil, fmt.Errorf("open resume session %q: %w", sessionID, err)
	}
	defer f.Close()

	state := &ResumeState{
		SessionID: sessionID,
		RepoDir:   repoDir,
		Items:     make(map[string]ResumeItem),
	}
	reader := bufio.NewReader(f)
	for {
		line, readErr := reader.ReadBytes('\n')
		if len(line) > 0 {
			if err := state.applyResumeLine(line); err != nil && !skipUnparseable {
				return nil, err
			}
		}
		if readErr == io.EOF {
			break

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. List actual sessions in ~/.opencodereview/<encoded-repo-path>/ and use an existing session id
  2. Check errors.Is(err, fs.ErrNotExist) vs permission/disk errors and fix HOME or permissions accordingly
  3. If the file is genuinely gone, start a fresh review instead of resuming

Example fix

// before
state, err := session.LoadResumeState(repoDir, sessionID)
// after
state, err := session.LoadResumeState(repoDir, sessionID)
if errors.Is(err, fs.ErrNotExist) {
	log.Printf("no prior session %q; starting fresh", sessionID)
	return runFreshReview(opts)
}
Defensive patterns

Strategy: fallback

Validate before calling

path, _ := session.SessionFilePath(repoDir, sessionID)
if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) {
	// no session to resume; go fresh
}

Type guard

func sessionExists(repoDir, sessionID string) bool {
	path, err := session.SessionFilePath(repoDir, sessionID)
	if err != nil { return false }
	_, statErr := os.Stat(path)
	return statErr == nil
}

Try / catch

state, err := session.LoadResumeState(repoDir, sessionID)
if err != nil {
	if errors.Is(err, fs.ErrNotExist) { return runFresh(opts) }
	return fmt.Errorf("resume: %w", err)
}

Prevention

When it happens

Trigger: Calling LoadResumeState or LoadReviewResumeState with a sessionID whose JSONL does not exist under ~/.opencodereview/, a misspelled/typo'd --session id, a file deleted by cleanup or another machine, or SessionFilePath failing to resolve the home dir is a separate error (this one is the os.Open failure).

Common situations: Users resume on a different machine or after wiping HOME; a stale session id from an old repo path encoding; the session file was pruned by a cleanup script; typo in the session id passed on the CLI.

Related errors


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