plandex-ai/plandex · error
no convo message ID for description: %v
Error message
no convo message ID for description: %v
What it means
Thrown when a plan description has pending build operations or invalidated build paths but its ConvoMessageId field is empty. The code requires every pending description to reference the conversation message that produced it, so it aborts instead of building an ActiveBuild with no ReplyId.
Source
Thrown at app/server/types/active_plan_pending_builds.go:44
if err != nil {
return nil, fmt.Errorf("error getting plan convo: %v", err)
}
} else {
convoMessages = convoMessagesArg
}
convoMessagesById := map[string]*db.ConvoMessage{}
for _, msg := range convoMessages {
convoMessagesById[msg.Id] = msg
}
activeBuildsByPath := map[string][]*ActiveBuild{}
for _, desc := range planDescs {
if (!desc.DidBuild && len(desc.Operations) > 0) || len(desc.BuildPathsInvalidated) > 0 {
if desc.ConvoMessageId == "" {
log.Printf("No convo message ID for description: %v\n", desc)
return nil, fmt.Errorf("no convo message ID for description: %v", desc)
}
if convoMessagesById[desc.ConvoMessageId] == nil {
log.Printf("No convo message for ID: %s\n", desc.ConvoMessageId)
return nil, fmt.Errorf("no convo message for ID: %s", desc.ConvoMessageId)
}
// convoMessage := convoMessagesById[desc.ConvoMessageId]
// replyParser := NewReplyParser()
// replyParser.AddChunk(convoMessage.Message, false)
// parserRes := replyParser.FinishAndRead()
numAdded := 0
for _, op := range desc.Operations {
if desc.DidBuild && !desc.BuildPathsInvalidated[op.Path] {
continueView on GitHub (pinned to e2d772072e)
Solutions
- Inspect the offending description (printed in the log line above the error) and fix its convo_message_id in the database.
- Rebuild or regenerate the plan's conversation descriptions so ConvoMessageId is populated.
- Skip or delete the orphaned description record if its builds are no longer needed.
- Add a DB constraint/validation on write so descriptions with operations always carry a ConvoMessageId.
Example fix
// before
if desc.ConvoMessageId == "" {
return nil, fmt.Errorf("no convo message ID for description: %v", desc)
}
// after (skip-and-warn instead of hard fail)
if desc.ConvoMessageId == "" {
log.Printf("skipping description %s with no convo message ID", desc.Id)
continue
} Defensive patterns
Strategy: validation
Validate before calling
for _, desc := range descs {
if (!desc.DidBuild && len(desc.Operations) > 0) || len(desc.BuildPathsInvalidated) > 0 {
if desc.ConvoMessageId == "" {
return fmt.Errorf("description %s has pending builds but no convo message ID", desc.Id)
}
}
} Type guard
func hasConvoMessageId(desc *types.ConvoMessageDescription) bool {
return desc != nil && desc.ConvoMessageId != ""
} Try / catch
builds, err := plan.PendingBuildsByPath(orgId, userId, nil)
if err != nil {
if strings.Contains(err.Error(), "no convo message ID for description") {
log.Printf("orphaned description detected; repairing descriptions before retry")
return repairDescriptions(plan.Id)
}
return err
} Prevention
- Always set ConvoMessageId when creating ConvoMessageDescription rows.
- Add a NOT NULL / CHECK constraint on convo_message_id for descriptions with operations.
- Backfill legacy rows missing the ID before running builds.
- Log and quarantine orphaned descriptions rather than leaving them in the active set.
When it happens
Trigger: A conversation message description row exists in the DB with empty convo_message_id while having len(Operations) > 0 with !DidBuild, or non-empty BuildPathsInvalidated; typically a legacy or corrupted description record.
Common situations: Older plan data created before ConvoMessageId was always populated; manually edited or imported DB rows; a bug in the description-creation path that skipped setting ConvoMessageId.
Related errors
- no convo message for ID: %s
- Stream has no branch
- Stream has no plan
- connection to plan stream timed out due to missing heartbeat
- error loading accounts: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/e8f1b3a36bfd5858.
Report an issue: GitHub.