plandex-ai/plandex · error
error storing convo message: %v
Error message
error storing convo message: %v
What it means
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.
Source
Thrown at app/server/model/plan/stop.go:47
if !active.BuildOnly && !active.RepliesFinished {
num := active.MessageNum + 1
userMsg := db.ConvoMessage{
OrgId: currentOrgId,
PlanId: planId,
UserId: currentUserId,
Role: openai.ChatMessageRoleAssistant,
Tokens: active.NumTokens,
Num: num,
Stopped: true,
Message: active.CurrentReplyContent,
}
_, err := db.StoreConvoMessage(repo, &userMsg, currentUserId, branch, true)
if err != nil {
return fmt.Errorf("error storing convo message: %v", err)
}
}
return nil
}
View on GitHub (pinned to e2d772072e)
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.
Example fix
// before
if err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {
http.Error(w, err.Error(), 500)
}
// after
if err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {
log.Printf("store partial reply: %v", err) // read wrapped DB cause
if !strings.Contains(err.Error(), "context canceled") {
http.Error(w, "failed to save partial reply, see server logs", 500)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if repo == nil || currentUserId == "" || currentOrgId == "" || planId == "" {
return errors.New("cannot store partial reply: missing repo/org/user/plan identifiers")
}
// optionally ping DB before the write
if err := db.HealthCheck(); err != nil {
return fmt.Errorf("db unavailable, will not store partial reply: %w", err)
} Try / catch
if err := plan.StorePartialReply(repo, planId, branch, userId, orgId); err != nil {
var inner error
fmt.Sscanf(err.Error(), "error storing convo message: %v", &inner) // inspect wrapped cause
log.Printf("partial reply store failed: %v", err)
// do not lose the partial reply: retry once, then queue for later persistence
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error storing convo message description: %v
- error storing description: %v
- Error setting plan status to replying: %v
- error updating context: %v
- error invalidating conflicted results: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f009ec294a048c15.
Report an issue: GitHub.