{"record":{"id":"f009ec294a048c15","repo":"plandex-ai/plandex","slug":"error-storing-convo-message-v","errorCode":null,"errorMessage":"error storing convo message: %v","messagePattern":"error storing convo message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/model/plan/stop.go","lineNumber":47,"sourceCode":"\n\tif !active.BuildOnly && !active.RepliesFinished {\n\t\tnum := active.MessageNum + 1\n\n\t\tuserMsg := db.ConvoMessage{\n\t\t\tOrgId:   currentOrgId,\n\t\t\tPlanId:  planId,\n\t\t\tUserId:  currentUserId,\n\t\t\tRole:    openai.ChatMessageRoleAssistant,\n\t\t\tTokens:  active.NumTokens,\n\t\t\tNum:     num,\n\t\t\tStopped: true,\n\t\t\tMessage: active.CurrentReplyContent,\n\t\t}\n\n\t\t_, err := db.StoreConvoMessage(repo, &userMsg, currentUserId, branch, true)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error storing convo message: %v\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":29,"sourceCodeEnd":53,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/stop.go#L29-L53","documentation":"StorePartialReply persists the truncated assistant reply as a ConvoMessage via db.StoreConvoMessage. When that database write fails, the error is wrapped as \"error storing convo message: %v\" and returned. The underlying cause is whatever StoreConvoMessage hit — most commonly a database connectivity or constraint failure.","triggerScenarios":"db.StoreConvoMessage(repo, &userMsg, currentUserId, branch, true) returns a non-nil error while stopping a plan mid-reply: DB unreachable, transaction conflict, invalid org/user/plan id foreign keys, or a lock/timeout on the convo_messages table.","commonSituations":"Database down or connection pool exhausted under load; stopping a plan whose org/user ids no longer exist in the DB (user deleted mid-session); migration mismatch after an upgrade; disk-full or timeout on the DB host during a burst of stop requests.","solutions":["Inspect the wrapped inner error (everything after 'error storing convo message:') to identify the DB failure and fix that root cause.","Verify database connectivity and health (connection limits, migrations) on the Plandex server host.","Retry the stop/store operation once the DB is reachable — the partial reply is only persisted once.","If the org/user referenced was deleted, clean up or recreate the account record before stopping plans tied to it."],"exampleFix":"// before\nif err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {\n    http.Error(w, err.Error(), 500)\n}\n// after\nif err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {\n    log.Printf(\"store partial reply: %v\", err) // read wrapped DB cause\n    if !strings.Contains(err.Error(), \"context canceled\") {\n        http.Error(w, \"failed to save partial reply, see server logs\", 500)\n    }\n}","handlingStrategy":"try-catch","validationCode":"if repo == nil || currentUserId == \"\" || currentOrgId == \"\" || planId == \"\" {\n    return errors.New(\"cannot store partial reply: missing repo/org/user/plan identifiers\")\n}\n// optionally ping DB before the write\nif err := db.HealthCheck(); err != nil {\n    return fmt.Errorf(\"db unavailable, will not store partial reply: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {\n    var inner error\n    fmt.Sscanf(err.Error(), \"error storing convo message: %v\", &inner) // inspect wrapped cause\n    log.Printf(\"partial reply store failed: %v\", err)\n    // do not lose the partial reply: retry once, then queue for later persistence\n    return err\n}","preventionTips":["Monitor DB health and connection-pool saturation on the server.","Keep org/user foreign keys intact; cascade plans when deleting accounts.","Apply DB migrations before deploying new Plandex versions.","Unwrap and log the wrapped inner error, not just the top-level message."],"tags":["go","database","persistence","error-wrapping"],"backgroundTag":"database-write-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}