charmbracelet/crush · error
session not found: %s
Error message
session not found: %s
What it means
resolveSessionID lets users pass a full session ID or a unique hash prefix. After scanning all sessions, if no session's ID (or hash prefix) matches the given argument, this 'session not found' error is returned. It is a user-input error, not a system failure.
Source
Thrown at internal/cmd/session.go:238
return s, nil
}
// List all sessions and check for hash matches
sessions, err := svc.List(ctx)
if err != nil {
return session.Session{}, err
}
var matches []session.Session
for _, s := range sessions {
hash := session.HashID(s.ID)
if hash == id || strings.HasPrefix(hash, id) {
matches = append(matches, s)
}
}
if len(matches) == 0 {
return session.Session{}, fmt.Errorf("session not found: %s", id)
}
if len(matches) == 1 {
return matches[0], nil
}
// Ambiguous - show matches like Git does
var sb strings.Builder
fmt.Fprintf(&sb, "session ID '%s' is ambiguous. Matches:\n\n", id)
for _, m := range matches {
hash := session.HashID(m.ID)
created := time.Unix(m.CreatedAt, 0).Format("2006-01-02")
// Keep title on one line by replacing newlines with spaces, and truncate.
title := strings.ReplaceAll(m.Title, "\n", " ")
title = ansi.Truncate(title, 50, "…")
fmt.Fprintf(&sb, " %s... %q (created %s)\n", hash[:12], title, created)
}
sb.WriteString("\nUse more characters or the full hash")View on GitHub (pinned to 7944b8e522)
Solutions
- Run `crush session list` (or with --json) to see valid session IDs and copy one exactly
- Check you are pointing at the same --data-dir used when the session was created
- Verify the prefix is long enough and matches at least one session hash
- If ambiguous vs missing confusion matters, note that multiple matches raise a separate ambiguity error — this one means zero matches
Example fix
// before crush session show abc12 // after crush session list # find the correct ID crush session show abc123def456... # use full/valid ID
Defensive patterns
Strategy: validation
Validate before calling
// validate the ID against the session list before resolving
list, _ := svc.sessions.List(ctx)
id := args[0]
found := false
for _, s := range list {
if s.ID == id || strings.HasPrefix(strings.TrimPrefix(s.ID, "session_"), id) {
found = true
break
}
}
if !found {
return fmt.Errorf("unknown session %q; run 'crush session list' to see valid IDs", id)
} Try / catch
sess, err := resolveSessionID(ctx, svc.sessions, args[0])
if err != nil {
var nfErr *NotFoundError
if errors.As(err, &nfErr) {
fmt.Fprintf(os.Stderr, "No session matching %q. Try 'crush session list'.\n", args[0])
os.Exit(1)
}
return err
} Prevention
- Copy full session IDs from `crush session list --json` rather than typing prefixes
- Confirm the --data-dir matches where the session was created
- Tab-complete or script ID resolution against the live list
- Remember deleted sessions disappear from the ID space
When it happens
Trigger: `crush session show|delete|rename <id>` called with an ID/prefix that matches zero sessions — typo, session already deleted, or wrong data directory (different DB).
Common situations: Copy-pasting an ID from another machine's data dir; truncating a hash prefix so it matches nothing; referencing a session deleted earlier; case-sensitivity mismatch in the prefix.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- cannot continue an agent tool session: %s
- session not found: %s
- cannot continue a child session: %s
- no sessions found to continue
- failed to resolve session: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/fbda30123b102bdb.
Report an issue: GitHub.