plandex-ai/plandex · error

planningSharedMsgs not supported during implementation stage

Error message

planningSharedMsgs not supported during implementation stage - only basic or smart context is supported

What it means

getTellSysPrompt builds the system prompt for LLM plan-execution calls. When the plan is in the implementation stage it requires implementationMsgs (context built with 'basic' or 'smart' context mode) and forbids planningSharedMsgs, which only makes sense in the planning stage. If a planning-stage shared message slice is passed to an implementation-stage call, the function refuses to build a prompt and returns this error instead of silently producing a malformed prompt.

Source

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

				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

  1. Ensure the caller builds context via the implementation/basic-or-smart path so planningSharedMsgs is nil when the stage is implementation
  2. Check the subtask/stage detection: if the plan should still be planning, fix why it is flagged as implementation
  3. If using a custom context mode that yields shared planning messages, switch the plan/task to basic or smart context
  4. Pass implementationMsgs alongside a nil planningSharedMsgs, or run with dryRunWithoutContext for token estimation

Example fix

// before
sysPrompt, err := getTellSysPrompt(state, req, planningSharedMsgs, nil, false)
// after
var planningMsgs []*types.ExtendedChatMessagePart // nil during implementation stage
sysPrompt, err := getTellSysPrompt(state, req, planningMsgs, implementationMsgs, false)
Defensive patterns

Strategy: validation

Validate before calling

if stage == "implementation" && planningSharedMsgs != nil {
    planningSharedMsgs = nil // implementation stage only accepts basic/smart context
}
sysPrompt, err := getTellSysPrompt(state, req, planningSharedMsgs, implementationMsgs, dryRun)

Type guard

func planningContextAllowed(stage string, planningMsgs []*types.ExtendedChatMessagePart) bool {
    return stage != "implementation" || planningMsgs == nil
}

Try / catch

sysPrompt, err := getTellSysPrompt(state, req, planningSharedMsgs, implementationMsgs, dryRun)
if err != nil && strings.Contains(err.Error(), "planningSharedMsgs not supported") {
    sysPrompt, err = getTellSysPrompt(state, req, nil, implementationMsgs, dryRun)
}

Prevention

When it happens

Trigger: Calling getTellSysPrompt (via execTellPlan or a dry-run token calculation dryRunCalculateTokensWithoutContext) with the current subtask in the implementation stage while the caller passes a non-nil planningSharedMsgs — i.e. the wrong context-construction path (planning shared context) was selected for an implementation-stage request.

Common situations: A context-mode mismatch: the plan moved from planning to implementation but the caller is still using context messages assembled for planning; custom context ('whole'/'file-map' style) configurations that produce shared planning messages; code paths or integrations that reuse planning context for implementation-stage model calls.

Related errors


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