charmbracelet/crush · error

session ID %q is ambiguous (%d matches)

Error message

session ID %q is ambiguous (%d matches)

What it means

When resolving a session by short hash prefix, if more than one session's hash starts with the given id, resolveSessionByID refuses to guess and reports the number of matches. This protects against resuming the wrong session from an ambiguous prefix.

Source

Thrown at internal/cmd/run.go:728

	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. Lengthen the hash prefix until it is unique (6-8 characters is usually enough).
  2. Use the full session UUID for an exact match.
  3. Run `crush session list` and copy the exact short hash shown for the target session.

Example fix

// before
crush run --session ab "prompt"        # ambiguous: 3 matches
// after
crush run --session ab12cd "prompt"    # unique prefix
Defensive patterns

Strategy: validation

Validate before calling

sessions, _ := c.ListSessions(ctx, wsID)
n := 0
for _, s := range sessions {
    if strings.HasPrefix(session.HashID(s.ID), short) {
        n++
    }
}
if n > 1 {
    return fmt.Errorf("prefix %q is ambiguous (%d matches); use a longer prefix", short, n)
}

Type guard

func uniquePrefix(sessions []proto.Session, prefix string) bool {
    n := 0
    for _, s := range sessions {
        if strings.HasPrefix(session.HashID(s.ID), prefix) {
            if n++; n > 1 {
                return false
            }
        }
    }
    return n == 1
}

Try / catch

sess, err := resolveSessionByID(ctx, c, wsID, short)
if err != nil && strings.Contains(err.Error(), "is ambiguous") {
    return fmt.Errorf("widen the prefix; try: crush session list | grep ^%s", short)
}

Prevention

When it happens

Trigger: Passing a hash prefix shorter than needed such that multiple sessions share it as a prefix (e.g. `ab` matching ab12..., ab3f...), typically with 1-2 character prefixes or after many sessions accumulate.

Common situations: Hand-typing a very short prefix from memory; scripting with a fixed short prefix; sessions with similar timestamps producing hashes with common prefixes.

Related errors


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