plandex-ai/plandex · error

implementationMsgs not supported during planning phase

Error message

implementationMsgs not supported during planning phase

What it means

Thrown by getTellSysPrompt (tell_sys_prompt.go:123) when the caller passes non-empty implementationMsgs while the current tell stage is Planning. Planning-stage prompts must be built only from planningSharedMsgs and plannerOnlyMsgs; implementation messages belong exclusively to the Implementation stage, so passing both indicates a caller bug and the library rejects the combination instead of silently mixing stages.

Source

Thrown at app/server/model/plan/tell_sys_prompt.go:123

				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,
					})
				}
			}
		}

		for _, msg := range plannerOnlyMsgs {
			sysParts = append(sysParts, *msg)
		}

		if len(implementationMsgs) > 0 {
			return nil, fmt.Errorf("implementationMsgs not supported during planning phase")
		}

	} else if currentStage.TellStage == shared.TellStageImplementation {
		if state.currentSubtask == nil {
			return nil, errors.New(AllTasksCompletedMsg)
		}

		if len(state.subtasks) > 0 {
			sysParts = append(sysParts, types.ExtendedChatMessagePart{
				Type: openai.ChatMessagePartTypeText,
				Text: prompts.GetImplementationPrompt(state.currentSubtask.Title),
			})
			sysParts = append(sysParts,
				types.ExtendedChatMessagePart{
					Type: openai.ChatMessagePartTypeText,
					Text: state.formatSubtasks(),
					CacheControl: &types.CacheControlSpec{
						Type: types.CacheControlTypeEphemeral,

View on GitHub (pinned to e2d772072e)

Solutions

  1. Set implementationMsgs to nil/empty when calling getTellSysPrompt during the planning stage.
  2. Build getTellSysPromptParams per stage: planningSharedMsgs+planningPhaseOnlyMsgs for planning, implementationMsgs for implementation.
  3. Audit the stage-transition code so implementation-phase context is cleared when TellStage switches to planning.
  4. Add an assertion early in the caller that only the stage-appropriate fields are populated.

Example fix

// before
params := getTellSysPromptParams{
    planStageSharedMsgs: sharedMsgs,
    implementationMsgs: implMsgs, // wrongly carried over
}
// after
params := getTellSysPromptParams{
    planStageSharedMsgs: sharedMsgs,
    planningPhaseOnlyMsgs: plannerOnly,
    implementationMsgs: nil, // not allowed during planning
}
Defensive patterns

Strategy: validation

Validate before calling

func validatePromptParamsForStage(stage shared.TellStage, p getTellSysPromptParams) error {
    if stage == shared.TellStagePlanning && len(p.implementationMsgs) > 0 {
        return fmt.Errorf("implementationMsgs must be empty during planning stage")
    }
    return nil
}

Type guard

func planningParamsOnly(p getTellSysPromptParams) bool {
    return len(p.implementationMsgs) == 0
}

Try / catch

if err := validatePromptParamsForStage(state.currentStage.TellStage, params); err != nil {
    // clear stage-inappropriate fields and rebuild
    params.implementationMsgs = nil
}
sysParts, err := state.getTellSysPrompt(params)
if err != nil {
    return fmt.Errorf("planning prompt build failed: %w", err)
}

Prevention

When it happens

Trigger: A caller (e.g. execTellPlan or a custom pipeline) builds getTellSysPromptParams with implementationMsgs populated while state.currentStage.TellStage == shared.TellStagePlanning — usually from incorrectly reusing implementation-phase context messages across a stage transition or from a miswired stage switch.

Common situations: Refactoring prompt assembly and accidentally reusing the same params struct for both stages; a stage transition that keeps stale implementationMsgs in the params; custom tooling that assumes both message sets can be combined in one prompt.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/802fbce8cef7ab25. Report an issue: GitHub.