{"record":{"id":"a461e407687945fb","repo":"plandex-ai/plandex","slug":"implementationmsgs-is-nil-required-for-implement","errorCode":null,"errorMessage":"implementationMsgs is nil - required for implementation stage","messagePattern":"implementationMsgs is nil - required for implementation stage","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/model/plan/tell_sys_prompt.go","lineNumber":173,"sourceCode":"\t\t\tif len(active.SkippedPaths) > 0 {\n\t\t\t\tskippedPrompt := prompts.SkippedPathsPrompt\n\t\t\t\tfor skippedPath := range active.SkippedPaths {\n\t\t\t\t\tskippedPrompt += fmt.Sprintf(\"- %s\\n\", skippedPath)\n\t\t\t\t}\n\t\t\t\tsysParts = append(sysParts, types.ExtendedChatMessagePart{\n\t\t\t\t\tType: openai.ChatMessagePartTypeText,\n\t\t\t\t\tText: skippedPrompt,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif implementationMsgs != nil {\n\t\t\tfor _, msg := range implementationMsgs {\n\t\t\t\tsysParts = append(sysParts, *msg)\n\t\t\t}\n\t\t} else if !params.dryRunWithoutContext {\n\t\t\tlog.Println(\"implementationMsgs is nil - required for implementation stage\")\n\t\t\treturn nil, fmt.Errorf(\"implementationMsgs is nil - required for implementation stage\")\n\t\t}\n\n\t\tif planningSharedMsgs != nil {\n\t\t\tlog.Println(\"planningSharedMsgs not supported during implementation stage - only basic or smart context is supported\")\n\t\t\treturn nil, fmt.Errorf(\"planningSharedMsgs not supported during implementation stage - only basic or smart context is supported\")\n\t\t}\n\t}\n\n\treturn sysParts, nil\n}\n","sourceCodeStart":155,"sourceCodeEnd":184,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/tell_sys_prompt.go#L155-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nparams := getTellSysPromptParams{\n    planningSharedMsgs: sharedMsgs, // wrong stage\n    // implementationMsgs missing\n}\n// after\nparams := getTellSysPromptParams{\n    implementationMsgs: implCtxMsgs, // required for implementation stage\n    planningSharedMsgs: nil,\n}","handlingStrategy":"validation","validationCode":"func canBuildImplementationPrompt(p getTellSysPromptParams, dryRun bool) error {\n    if p.implementationMsgs == nil && !dryRun {\n        return fmt.Errorf(\"implementation stage requires implementationMsgs\")\n    }\n    if p.planningSharedMsgs != nil {\n        return fmt.Errorf(\"planningSharedMsgs not allowed during implementation stage\")\n    }\n    return nil\n}","typeGuard":"func hasImplementationMsgs(p getTellSysPromptParams) bool {\n    return p.dryRunWithoutContext || p.implementationMsgs != nil\n}","tryCatchPattern":"sysParts, err := state.getTellSysPrompt(params)\nif err != nil {\n    if strings.Contains(err.Error(), \"implementationMsgs is nil\") {\n        if implMsgs, lerr := loadImplementationContext(state); lerr == nil {\n            params.implementationMsgs = implMsgs\n            sysParts, err = state.getTellSysPrompt(params)\n        }\n    }\n    if err != nil { return err }\n}","preventionTips":["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."],"tags":["prompt","implementation-stage","missing-context","internal-state"],"backgroundTag":"missing-required-context","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}