charmbracelet/crush · error

failed to get session: %w

Error message

failed to get session: %w

What it means

Run wraps failures from the session store lookup with 'failed to get session: %w'. The agent could not load the session identified by call.SessionID before building the prompt, so the run aborts with the underlying store error attached.

Source

Thrown at internal/agent/agent.go:695

		systemPrompt += "\n\n<mcp-instructions>\n" + s + "\n</mcp-instructions>"
	}

	if len(agentTools) > 0 {
		// Add Anthropic caching to the last tool.
		agentTools[len(agentTools)-1].SetProviderOptions(a.getCacheControlOptions())
	}

	agent := fantasy.NewAgent(
		largeModel.Model,
		fantasy.WithSystemPrompt(systemPrompt),
		fantasy.WithTools(agentTools...),
		fantasy.WithUserAgent(userAgent),
	)

	sessionLock := sync.Mutex{}
	currentSession, err := a.sessions.Get(ctx, call.SessionID)
	if err != nil {
		return nil, fmt.Errorf("failed to get session: %w", err)
	}

	msgs, err := a.getSessionMessages(ctx, currentSession)
	if err != nil {
		return nil, fmt.Errorf("failed to get session messages: %w", err)
	}

	// Generate title from the first real (non-shell) user prompt.
	// can take tens of seconds. Blocking Run on it delays the
	// response to the caller. Use a detached context so the title
	// goroutine survives Run's cancel.
	if !hasUserTextMessage(msgs) {
		titleCtx := context.WithoutCancel(ctx)
		go a.GenerateTitle(titleCtx, call.SessionID, call.Prompt)
	}

	// Add the user message to the session.
	_, err = a.createUserMessage(ctx, call)

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Verify the SessionID passed in the call exists (sessions.Get or session list) before running
  2. Check DB health (file path, permissions, locks) if IDs are valid
  3. Inspect the wrapped %w error to distinguish not-found vs storage failure

Example fix

// before
out, err := agent.Run(ctx, agent.Call{SessionID: id})
// after
if _, err := sessions.Get(ctx, id); err != nil {
    return fmt.Errorf("session %s unavailable: %w", id, err)
}
out, err := agent.Run(ctx, agent.Call{SessionID: id})
Defensive patterns

Strategy: validation

Validate before calling

if _, err := sessions.Get(ctx, call.SessionID); err != nil {
    return fmt.Errorf("cannot run: session %s missing: %w", call.SessionID, err)
}

Try / catch

out, err := agent.Run(ctx, call)
if err != nil && strings.HasPrefix(err.Error(), "failed to get session") {
    // inspect errors.Unwrap for not-found vs db failure
}

Prevention

When it happens

Trigger: a.sessions.Get(ctx, call.SessionID) fails inside Run (or Summarize via Run) — session ID does not exist, DB error, or the context is cancelled mid-query.

Common situations: Caller passes a stale or deleted session ID; SQLite file locked/corrupt; request context cancelled while the query runs; session created in another DB instance.

Related errors


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