charmbracelet/crush · error

session %q not found

Error message

session %q not found

What it means

resolveSessionByID first tries a direct GetSession by full ID; on failure it lists sessions and matches short hash prefixes. If no session's full ID or hash prefix equals the given id, it returns "session %q not found". Note it cannot distinguish a bad ID from a listing failure propagated earlier.

Source

Thrown at internal/cmd/run.go:724

		return sess, nil
	}

	sessions, err := c.ListSessions(ctx, wsID)
	if err != nil {
		return nil, err
	}

	var matches []proto.Session
	for _, s := range sessions {
		hash := session.HashID(s.ID)
		if hash == id || strings.HasPrefix(hash, id) {
			matches = append(matches, s)
		}
	}

	switch len(matches) {
	case 0:
		return nil, fmt.Errorf("session %q not found", id)
	case 1:
		return &matches[0], nil
	default:
		return nil, fmt.Errorf("session ID %q is ambiguous (%d matches)", id, len(matches))
	}
}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Re-run `crush session list` in the same workspace and copy the ID/hash exactly.
  2. Use the full UUID instead of a short hash to avoid prefix issues.
  3. Confirm --data-dir matches the environment where the session was created.
  4. If gone, start a new session instead of resuming.

Example fix

// before
crush run --session ab12 "prompt"      # hash no longer exists
// after
crush session list                     # pick a current hash
crush run --session ab12cd34 "prompt"
Defensive patterns

Strategy: validation

Validate before calling

sessions, _ := c.ListSessions(ctx, wsID)
found := false
for _, s := range sessions {
    h := session.HashID(s.ID)
    if s.ID == id || h == id || strings.HasPrefix(h, id) {
        found = true
        break
    }
}
if !found {
    return fmt.Errorf("%s matches no current session; run 'crush session list'", id)
}

Type guard

func matchesSession(sessions []proto.Session, id string) bool {
    for _, s := range sessions {
        if s.ID == id || strings.HasPrefix(session.HashID(s.ID), id) {
            return true
        }
    }
    return false
}

Try / catch

sess, err := resolveSessionByID(ctx, c, wsID, id)
if err != nil && strings.HasSuffix(err.Error(), "not found") {
    log.Warnf("session %s gone; starting a new one", id)
    sess, err = c.CreateSession(ctx, wsID, "non-interactive")
}

Prevention

When it happens

Trigger: Passing a session ID/short hash to the command that resolves it (e.g. resuming a session by short hash) where the hash does not match any existing session in the workspace: mistyped prefix, session deleted, or wrong workspace/data-dir.

Common situations: Using a short hash copied from `crush session list` of a different project; too-short prefix after sessions were pruned; pointing at a fresh data directory in CI.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/e8a0a915db8994bf. Report an issue: GitHub.