plandex-ai/plandex · error
implementationMsgs is nil - required for implementation stag
Error message
implementationMsgs is nil - required for implementation stage
What it means
Thrown by getTellSysPrompt (tell_sys_prompt.go:173) when the tell stream is in the Implementation stage but implementationMsgs is nil and the call is not a dry run (params.dryRunWithoutContext is false). Implementation-stage system prompts require the implementation context messages (loaded file contexts relevant to the current subtask); without them the model would run with no implementation context, so the library errors out. Note nil triggers the error while an empty non-nil slice is accepted.
Source
Thrown at app/server/model/plan/tell_sys_prompt.go:173
if len(active.SkippedPaths) > 0 {
skippedPrompt := prompts.SkippedPathsPrompt
for skippedPath := range active.SkippedPaths {
skippedPrompt += fmt.Sprintf("- %s\n", skippedPath)
}
sysParts = append(sysParts, types.ExtendedChatMessagePart{
Type: openai.ChatMessagePartTypeText,
Text: skippedPrompt,
})
}
}
if implementationMsgs != nil {
for _, msg := range implementationMsgs {
sysParts = append(sysParts, *msg)
}
} else if !params.dryRunWithoutContext {
log.Println("implementationMsgs is nil - required for implementation stage")
return nil, fmt.Errorf("implementationMsgs is nil - required for implementation stage")
}
if planningSharedMsgs != nil {
log.Println("planningSharedMsgs not supported during implementation stage - only basic or smart context is supported")
return nil, fmt.Errorf("planningSharedMsgs not supported during implementation stage - only basic or smart context is supported")
}
}
return sysParts, nil
}
View on GitHub (pinned to e2d772072e)
Solutions
- Ensure the implementation-stage caller always populates implementationMsgs from the loaded file context for the current subtask (use an empty non-nil slice if intentionally empty).
- Check why subtask context loading produced nil — verify activate paths exist and file loads succeed; log empty loads.
- For token-estimation or dry-run paths, set dryRunWithoutContext=true to bypass the requirement.
- Also clear planningSharedMsgs (leave nil) in the same params, since it is rejected in the implementation stage.
Example fix
// before
params := getTellSysPromptParams{
planningSharedMsgs: sharedMsgs, // wrong stage
// implementationMsgs missing
}
// after
params := getTellSysPromptParams{
implementationMsgs: implCtxMsgs, // required for implementation stage
planningSharedMsgs: nil,
} Defensive patterns
Strategy: validation
Validate before calling
func canBuildImplementationPrompt(p getTellSysPromptParams, dryRun bool) error {
if p.implementationMsgs == nil && !dryRun {
return fmt.Errorf("implementation stage requires implementationMsgs")
}
if p.planningSharedMsgs != nil {
return fmt.Errorf("planningSharedMsgs not allowed during implementation stage")
}
return nil
} Type guard
func hasImplementationMsgs(p getTellSysPromptParams) bool {
return p.dryRunWithoutContext || p.implementationMsgs != nil
} Try / catch
sysParts, err := state.getTellSysPrompt(params)
if err != nil {
if strings.Contains(err.Error(), "implementationMsgs is nil") {
if implMsgs, lerr := loadImplementationContext(state); lerr == nil {
params.implementationMsgs = implMsgs
sysParts, err = state.getTellSysPrompt(params)
}
}
if err != nil { return err }
} Prevention
- Initialize implementationMsgs to an empty non-nil slice before context loading so an empty load is distinguishable from a missing build.
- Log when subtask context loading returns no files; fail fast before prompt construction.
- Never pass planningSharedMsgs in implementation-stage params.
- Use dryRunWithoutContext=true only for token estimation, never real streams.
- Test resumed/retried plans to confirm implementation context is rebuilt for later subtasks.
When it happens
Trigger: execTellPlan enters TellStageImplementation (state.currentSubtask != nil) but the caller passes getTellSysPromptParams with implementationMsgs == nil during a real stream — e.g. context loading for the current subtask's paths returned nothing and the slice stayed nil, or the params assembly branch for implementation was skipped.
Common situations: Subtask's activate paths fail to load any files so the context builder yields nil; auto-load/context-update step silently skipped on retries or resumption of an existing plan; a regression where the implementation context is only built on the first subtask; direct pipeline calls that omit implementationMsgs.
Related errors
- planningSharedMsgs is empty - required for planning stage
- Prompt message isn't set
- implementationMsgs not supported during planning phase
- error prompting auto add domain users: %v
- failed to get map file info for %s - should already be set
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a461e407687945fb.
Report an issue: GitHub.