plandex-ai/plandex · error
error reading convo message: %v
Error message
error reading convo message: %v
What it means
GetConvoMessage reads a single message file (<messageId>.json) from the plan's convo directory with os.ReadFile and returns this error wrapping the *PathError on failure. Note there is no IsNotExist special case here (unlike GetPlanConvo), so a missing message — the most common cause — surfaces as this error too.
Source
Thrown at app/server/db/convo_helpers.go:90
convo = append(convo, convoMessage)
}
}
sort.Slice(convo, func(i, j int) bool {
return convo[i].CreatedAt.Before(convo[j].CreatedAt)
})
return convo, nil
}
func GetConvoMessage(orgId, planId, messageId string) (*ConvoMessage, error) {
convoDir := getPlanConversationDir(orgId, planId)
filePath := filepath.Join(convoDir, messageId+".json")
bytes, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("error reading convo message: %v", err)
}
var convoMessage ConvoMessage
err = json.Unmarshal(bytes, &convoMessage)
if err != nil {
return nil, fmt.Errorf("error unmarshalling convo message: %v", err)
}
return &convoMessage, nil
}
func StoreConvoMessage(repo *GitRepo, message *ConvoMessage, currentUserId, branch string, commit bool) (string, error) {
convoDir := getPlanConversationDir(message.OrgId, message.PlanId)
ts := time.Now().UTC()
if message.Id == "" {
message.Id = uuid.New().String()View on GitHub (pinned to e2d772072e)
Solutions
- Confirm the messageId (and orgId/planId) is correct and the message still exists: ls <convoDir>/<messageId>.json
- If the message was deleted by a plan reset/rollback, treat it as gone and refresh the convo listing
- Fix permissions/ownership on the convo directory if the underlying error is permission-denied
- Restore the file from backup if it was lost
- Check the storage volume for I/O errors if the underlying message indicates a hardware/filesystem issue
Example fix
// caller hardening: treat not-found distinctly
// before
msg, err := db.GetConvoMessage(orgId, planId, msgId)
// after
path := filepath.Join(db.GetPlanConversationDir(orgId, planId), msgId+".json")
if _, err := os.Stat(path); os.IsNotExist(err) {
return fmt.Errorf("message %s not found", msgId)
}
msg, err := db.GetConvoMessage(orgId, planId, msgId) Defensive patterns
Strategy: type-guard
Validate before calling
if messageId == "" || !uuid.IsValid(messageId) {
return fmt.Errorf("invalid message id %q", messageId)
}
path := filepath.Join(getPlanConversationDir(orgId, planId), messageId+".json")
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return ErrConvoMessageNotFound
}
} Type guard
func isConvoMessageNotFound(err error) bool {
return errors.Is(err, fs.ErrNotExist) || strings.Contains(err.Error(), "no such file")
} Try / catch
msg, err := db.GetConvoMessage(orgId, planId, messageId)
if err != nil {
if isConvoMessageNotFound(err) {
return http.StatusNotFound, fmt.Errorf("message %s not found", messageId)
}
return http.StatusInternalServerError, err
} Prevention
- Validate message ids as UUIDs before lookup
- Refresh client-side message references after plan resets/rollbacks
- Keep orgId/planId scoping correct to avoid cross-plan lookups
- Alert on permission errors in the data dir
When it happens
Trigger: os.ReadFile fails: the messageId does not exist (client passed a stale/deleted/wrong UUID, or the '.json' suffix handling was bypassed), wrong orgId/planId used to build the path, permission denied, or I/O error on the storage volume.
Common situations: Client or UI holding a reference to a message from before a plan was reset/rolled back; a cross-plan or cross-org message id used by mistake; files lost after an incomplete restore; permissions changed on the data dir.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- error reading settings-v2.json: %v
- failed to seek in temporary file: %w
- error reading convo dir: %v
- error reading convo file: %v
- error creating convo message descriptions dir: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/d6193c770b5bf175.
Report an issue: GitHub.