{"record":{"id":"93a7aaea6dd31133","repo":"charmbracelet/crush","slug":"failed-to-get-session-messages-w","errorCode":null,"errorMessage":"failed to get session messages: %w","messagePattern":"failed to get session messages: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/agent.go","lineNumber":700,"sourceCode":"\t\tagentTools[len(agentTools)-1].SetProviderOptions(a.getCacheControlOptions())\n\t}\n\n\tagent := fantasy.NewAgent(\n\t\tlargeModel.Model,\n\t\tfantasy.WithSystemPrompt(systemPrompt),\n\t\tfantasy.WithTools(agentTools...),\n\t\tfantasy.WithUserAgent(userAgent),\n\t)\n\n\tsessionLock := sync.Mutex{}\n\tcurrentSession, err := a.sessions.Get(ctx, call.SessionID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get session: %w\", err)\n\t}\n\n\tmsgs, err := a.getSessionMessages(ctx, currentSession)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get session messages: %w\", err)\n\t}\n\n\t// Generate title from the first real (non-shell) user prompt.\n\t// can take tens of seconds. Blocking Run on it delays the\n\t// response to the caller. Use a detached context so the title\n\t// goroutine survives Run's cancel.\n\tif !hasUserTextMessage(msgs) {\n\t\ttitleCtx := context.WithoutCancel(ctx)\n\t\tgo a.GenerateTitle(titleCtx, call.SessionID, call.Prompt)\n\t}\n\n\t// Add the user message to the session.\n\t_, err = a.createUserMessage(ctx, call)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tuserMsgCreated = true\n","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/agent.go#L682-L718","documentation":"Run wraps failures from getSessionMessages with 'failed to get session messages: %w'. After loading the session, the agent lists and post-processes its message history; a storage failure there aborts the run.","triggerScenarios":"a.getSessionMessages(ctx, currentSession) returns an error inside Run/Summarize — i.e. a.messages.List on the session ID fails (see error 88) or the summary-message splice logic errors.","commonSituations":"Message store unavailable or corrupted; session exists but its message rows are missing/inconsistent; context cancelled during the list query.","solutions":["Check the messages store (DB) health and that message rows for the session are intact","Retry the run if the underlying failure was transient (lock, cancelled context)","Inspect the wrapped cause; it is almost always a 'failed to list messages' error from getSessionMessages"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"out, err := agent.Run(ctx, call)\nvar storeErr error\nif err != nil && errors.As(err, &storeErr) {\n    log.Printf(\"history read failed: %v\", storeErr) // cause is 'failed to list messages'\n}","preventionTips":["Monitor message-store health; this error is downstream of messages.List","Retry runs on transient storage errors","Back up/verify the SQLite message tables"],"tags":["database","messages","error-wrapping"],"backgroundTag":"message-list-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}