{"record":{"id":"914d66837dcc771e","repo":"charmbracelet/crush","slug":"failed-to-create-user-message-w","errorCode":null,"errorMessage":"failed to create user message: %w","messagePattern":"failed to create user message: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/agent.go","lineNumber":1522,"sourceCode":"\treturn map[string]string{\n\t\t\"x-session-id\":       hash,\n\t\t\"x-session-affinity\": hash,\n\t}\n}\n\nfunc (a *sessionAgent) createUserMessage(ctx context.Context, call SessionAgentCall) (message.Message, error) {\n\tparts := []message.ContentPart{message.TextContent{Text: call.Prompt}}\n\tvar attachmentParts []message.ContentPart\n\tfor _, attachment := range call.Attachments {\n\t\tattachmentParts = append(attachmentParts, message.BinaryContent{Path: attachment.FilePath, MIMEType: attachment.MimeType, Data: attachment.Content})\n\t}\n\tparts = append(parts, attachmentParts...)\n\tmsg, err := a.messages.Create(ctx, call.SessionID, message.CreateMessageParams{\n\t\tRole:  message.User,\n\t\tParts: parts,\n\t})\n\tif err != nil {\n\t\treturn message.Message{}, fmt.Errorf(\"failed to create user message: %w\", err)\n\t}\n\treturn msg, nil\n}\n\nfunc (a *sessionAgent) preparePrompt(msgs []message.Message, supportsImages bool, attachments ...message.Attachment) ([]fantasy.Message, []fantasy.FilePart) {\n\tvar history []fantasy.Message\n\tif !a.isSubAgent {\n\t\thistory = append(history, fantasy.NewUserMessage(\n\t\t\tfmt.Sprintf(\n\t\t\t\t\"<system_reminder>%s</system_reminder>\",\n\t\t\t\t`This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.\nIf you are working on tasks that would benefit from a todo list please use the \"todos\" tool to create one.\nIf not, please feel free to ignore. Again do not mention this message to the user.`,\n\t\t\t),\n\t\t))\n\t}\n\t// Collect all tool call IDs present in assistant messages and all tool\n\t// result IDs present in tool messages. This lets us detect both orphaned","sourceCodeStart":1504,"sourceCodeEnd":1540,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/agent.go#L1504-L1540","documentation":"Raised when persisting the caller's prompt fails: a.messages.Create with Role User and the assembled parts (text plus attachmentParts) returns an error, and CreateAndStoreUserMessage-style code wraps it as 'failed to create user message: %w'.","triggerScenarios":"messages.Create fails while inserting the user message — DB insert error, constraint violation, oversized content/attachments, or cancelled context.","commonSituations":"SQLite locked or disk full; attachment payload too large for the storage schema; context deadline exceeded during a slow insert with many attachments.","solutions":["Check DB health (disk space, locks, WAL) since this is a write-path failure","Reduce attachment count/size and retry","Inspect the wrapped error for constraint violations (e.g. FK to a missing session)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure the target session exists before creating the user message\nif _, err := sessions.Get(ctx, call.SessionID); err != nil {\n    return fmt.Errorf(\"cannot store prompt: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"msg, err := createAndStoreUserMessage(ctx, call)\nif err != nil && strings.HasPrefix(err.Error(), \"failed to create user message\") {\n    return retry(ctx, func() error { _, err := createAndStoreUserMessage(ctx, call); return err })\n}","preventionTips":["Check disk space and SQLite lock contention on write-heavy sessions","Limit attachment size/count before building message parts","Use a context with adequate deadline for large inserts"],"tags":["database","write-failure","attachments"],"backgroundTag":"message-persist-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}