{"record":{"id":"802fbce8cef7ab25","repo":"plandex-ai/plandex","slug":"implementationmsgs-not-supported-during-planning-p","errorCode":null,"errorMessage":"implementationMsgs not supported during planning phase","messagePattern":"implementationMsgs not supported during planning phase","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/model/plan/tell_sys_prompt.go","lineNumber":123,"sourceCode":"\t\t\t\tif len(active.SkippedPaths) > 0 {\n\t\t\t\t\tskippedPrompt := prompts.SkippedPathsPrompt\n\t\t\t\t\tfor skippedPath := range active.SkippedPaths {\n\t\t\t\t\t\tskippedPrompt += fmt.Sprintf(\"- %s\\n\", skippedPath)\n\t\t\t\t\t}\n\t\t\t\t\tsysParts = append(sysParts, types.ExtendedChatMessagePart{\n\t\t\t\t\t\tType: openai.ChatMessagePartTypeText,\n\t\t\t\t\t\tText: skippedPrompt,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor _, msg := range plannerOnlyMsgs {\n\t\t\tsysParts = append(sysParts, *msg)\n\t\t}\n\n\t\tif len(implementationMsgs) > 0 {\n\t\t\treturn nil, fmt.Errorf(\"implementationMsgs not supported during planning phase\")\n\t\t}\n\n\t} else if currentStage.TellStage == shared.TellStageImplementation {\n\t\tif state.currentSubtask == nil {\n\t\t\treturn nil, errors.New(AllTasksCompletedMsg)\n\t\t}\n\n\t\tif len(state.subtasks) > 0 {\n\t\t\tsysParts = append(sysParts, types.ExtendedChatMessagePart{\n\t\t\t\tType: openai.ChatMessagePartTypeText,\n\t\t\t\tText: prompts.GetImplementationPrompt(state.currentSubtask.Title),\n\t\t\t})\n\t\t\tsysParts = append(sysParts,\n\t\t\t\ttypes.ExtendedChatMessagePart{\n\t\t\t\t\tType: openai.ChatMessagePartTypeText,\n\t\t\t\t\tText: state.formatSubtasks(),\n\t\t\t\t\tCacheControl: &types.CacheControlSpec{\n\t\t\t\t\t\tType: types.CacheControlTypeEphemeral,","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/tell_sys_prompt.go#L105-L141","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set implementationMsgs to nil/empty when calling getTellSysPrompt during the planning stage.","Build getTellSysPromptParams per stage: planningSharedMsgs+planningPhaseOnlyMsgs for planning, implementationMsgs for implementation.","Audit the stage-transition code so implementation-phase context is cleared when TellStage switches to planning.","Add an assertion early in the caller that only the stage-appropriate fields are populated."],"exampleFix":"// before\nparams := getTellSysPromptParams{\n    planStageSharedMsgs: sharedMsgs,\n    implementationMsgs: implMsgs, // wrongly carried over\n}\n// after\nparams := getTellSysPromptParams{\n    planStageSharedMsgs: sharedMsgs,\n    planningPhaseOnlyMsgs: plannerOnly,\n    implementationMsgs: nil, // not allowed during planning\n}","handlingStrategy":"validation","validationCode":"func validatePromptParamsForStage(stage shared.TellStage, p getTellSysPromptParams) error {\n    if stage == shared.TellStagePlanning && len(p.implementationMsgs) > 0 {\n        return fmt.Errorf(\"implementationMsgs must be empty during planning stage\")\n    }\n    return nil\n}","typeGuard":"func planningParamsOnly(p getTellSysPromptParams) bool {\n    return len(p.implementationMsgs) == 0\n}","tryCatchPattern":"if err := validatePromptParamsForStage(state.currentStage.TellStage, params); err != nil {\n    // clear stage-inappropriate fields and rebuild\n    params.implementationMsgs = nil\n}\nsysParts, err := state.getTellSysPrompt(params)\nif err != nil {\n    return fmt.Errorf(\"planning prompt build failed: %w\", err)\n}","preventionTips":["Construct getTellSysPromptParams inside a per-stage builder function.","Clear implementationMsgs when transitioning from implementation back to planning.","Add a pre-call assertion that only stage-appropriate message fields are set.","Cover stage transitions in tests (planning -> implementation -> planning)."],"tags":["prompt","planning-stage","invalid-arguments","internal-state"],"backgroundTag":"invalid-stage-parameters","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}