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

  1. Continue the parent session ID (sess.ParentSessionID) instead of the child.
  2. Filter session listings to top-level sessions (ParentSessionID == "") when scripting.
  3. 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

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


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