plandex-ai/plandex · error
Prompt message isn't set
Error message
Prompt message isn't set
What it means
Thrown when the promptMessage produced by state.resolvePromptMessage is nil at the point where execTellPlan appends it to the messages slice. The library treats a nil prompt as an unrecoverable internal state bug — no user prompt can be sent to the LLM — so it reports the error, sends a 500 ApiError on StreamDoneCh, and returns.
Source
Thrown at app/server/model/plan/tell_exec.go:362
active.StreamDoneCh <- &shared.ApiError{
Type: shared.ApiErrorTypeOther,
Status: http.StatusInternalServerError,
Msg: "Token limit exceeded before adding conversation",
}
return
}
if !state.addConversationMessages() {
return
}
// add the prompt message to the end of the messages slice
if promptMessage != nil {
state.messages = append(state.messages, *promptMessage)
} else {
log.Println("promptMessage is nil")
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("promptMessage is nil"))
active.StreamDoneCh <- &shared.ApiError{
Type: shared.ApiErrorTypeOther,
Status: http.StatusInternalServerError,
Msg: "Prompt message isn't set",
}
return
}
state.replyId = uuid.New().String()
state.replyParser = types.NewReplyParser()
if missingFileResponse != "" && !state.handleMissingFileResponse(unfinishedSubtaskReasoning) {
return
}
// filter out any messages that are empty
state.messages = model.FilterEmptyMessages(state.messages)View on GitHub (pinned to e2d772072e)
Solutions
- Re-send the tell request with a non-empty prompt
- Check resolvePromptMessage logic for branches that can return ok=true with a nil message
- Upgrade/patch the plan model code where the nil check happens too late (after token estimation uses *promptMessage)
- Report to maintainers with server logs if prompt was non-empty
Example fix
// before
promptMessage, ok := state.resolvePromptMessage(unfinishedSubtaskReasoning)
if !ok { return }
// after: fail fast with a clear message before using it
promptMessage, ok := state.resolvePromptMessage(unfinishedSubtaskReasoning)
if !ok || promptMessage == nil {
active.StreamDoneCh <- &shared.ApiError{Type: shared.ApiErrorTypeOther, Status: http.StatusBadRequest, Msg: "prompt is empty"}
return
} Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(prompt) == "" {
return errors.New("prompt must be a non-empty string before calling Tell")
} Try / catch
if apiErr := <-active.StreamDoneCh; apiErr != nil && strings.Contains(apiErr.Msg, "Prompt message isn't set") {
// resend with a valid non-empty prompt
} Prevention
- Always validate prompt text is non-empty/whitespace-free before invoking Tell
- Add an early nil/ok check right after resolvePromptMessage
- Cover resolvePromptMessage branches with tests asserting a non-nil message on ok==true
When it happens
Trigger: resolvePromptMessage returned ok=true earlier but produced a nil message (e.g. empty prompt input or an internal branch that fails to build the ExtendedChatMessage), or the prompt message pointer was invalidated between resolution and use.
Common situations: Sending a tell request with empty/whitespace-only prompt text; internal refactors changing resolvePromptMessage semantics; race where the prompt is cleared mid-request.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Error storing plan result: planRes is nil
- Error getting tell sys prompt for dry run token calculation
- planningSharedMsgs is empty - required for planning stage
- implementationMsgs not supported during planning phase
- implementationMsgs is nil - required for implementation stag
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/449a9a5f579752ac.
Report an issue: GitHub.