charmbracelet/crush · error
cannot continue a child session: %s
Error message
cannot continue a child session: %s
What it means
The referenced session exists but has a non-empty ParentSessionID, meaning it is a child session (created for a sub-task or fork). Continuation is only supported for top-level sessions, so resolveSession refuses to resume a child directly.
Source
Thrown at internal/app/app.go:249
app.herdrClient.SetSessionID(sessionID)
}
// resolveSession resolves which session to use for a non-interactive run
// If continueSessionID is set, it looks up that session by ID
// If useLast is set, it returns the most recently updated top-level session
// Otherwise, it creates a new session
func (app *App) resolveSession(ctx context.Context, continueSessionID string, useLast bool) (session.Session, error) {
switch {
case continueSessionID != "":
if app.Sessions.IsAgentToolSession(continueSessionID) {
return session.Session{}, fmt.Errorf("cannot continue an agent tool session: %s", continueSessionID)
}
sess, err := app.Sessions.Get(ctx, continueSessionID)
if err != nil {
return session.Session{}, fmt.Errorf("session not found: %s", continueSessionID)
}
if sess.ParentSessionID != "" {
return session.Session{}, fmt.Errorf("cannot continue a child session: %s", continueSessionID)
}
return sess, nil
case useLast:
sess, err := app.Sessions.GetLast(ctx)
if err != nil {
return session.Session{}, fmt.Errorf("no sessions found to continue")
}
return sess, nil
default:
return app.Sessions.Create(ctx, agent.DefaultSessionName)
}
}
// RunNonInteractive runs the application in non-interactive mode with the
// given prompt, printing to stdout.
func (app *App) RunNonInteractive(ctx context.Context, output io.Writer, prompt, largeModel, smallModel string, hideSpinner bool, continueSessionID string, useLast bool) error {View on GitHub (pinned to 7944b8e522)
Solutions
- Continue the parent session ID (sess.ParentSessionID) instead of the child.
- Filter session listings to top-level sessions (ParentSessionID == "") when scripting.
- Start a fresh session if the child context must be re-run standalone.
Example fix
// before crush run --continue <child-session-id> "continue" // after crush run --continue <parent-session-id> "continue"
Defensive patterns
Strategy: validation
Validate before calling
sess, err := app.Sessions.Get(ctx, sessionID)
if err == nil && sess.ParentSessionID != "" {
return fmt.Errorf("%s is a child session; continue %s instead", sessionID, sess.ParentSessionID)
} Type guard
func isTopLevel(s session.Session) bool { return s.ParentSessionID == "" } Try / catch
if err != nil {
if strings.HasPrefix(err.Error(), "cannot continue a child session") {
// look up sess.ParentSessionID and retry with it
}
return err
} Prevention
- Filter session listings to ParentSessionID == "" when selecting sessions to resume.
- Treat child sessions as internal implementation detail of task/fork flows.
When it happens
Trigger: Running with continueSessionID set to a child/forked session ID — the session was created as part of a task/fork flow and carries a parent reference.
Common situations: Picking the newest row from the sessions table without filtering by ParentSessionID; intentionally trying to resume a sub-agent conversation; UIs that show child sessions alongside parent ones.
Related errors
- cannot continue an agent tool session: %s
- session not found: %s
- no sessions found to continue
- failed to resolve session: %w
- failed to initialize config: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/17c38f9a02890ac4.
Report an issue: GitHub.