{"record":{"id":"3d04b272bf7328e9","repo":"plandex-ai/plandex","slug":"unknown-tell-stage","errorCode":null,"errorMessage":"Unknown tell stage","messagePattern":"Unknown tell stage","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/model/plan/tell_exec.go","lineNumber":196,"sourceCode":"\n\tvar tentativeModelConfig shared.ModelRoleConfig\n\tvar tentativeMaxTokens int\n\tif state.currentStage.TellStage == shared.TellStagePlanning {\n\t\tif state.currentStage.PlanningPhase == shared.PlanningPhaseContext {\n\t\t\tlog.Println(\"Tell plan - isContextStage - setting modelConfig to context loader\")\n\t\t\ttentativeModelConfig = state.settings.GetModelPack().GetArchitect()\n\t\t\ttentativeMaxTokens = state.settings.GetArchitectEffectiveMaxTokens()\n\t\t} else {\n\t\t\tplannerConfig := state.settings.GetModelPack().Planner\n\t\t\ttentativeModelConfig = plannerConfig.ModelRoleConfig\n\t\t\ttentativeMaxTokens = state.settings.GetPlannerEffectiveMaxTokens()\n\t\t}\n\t} else if state.currentStage.TellStage == shared.TellStageImplementation {\n\t\ttentativeModelConfig = state.settings.GetModelPack().GetCoder()\n\t\ttentativeMaxTokens = state.settings.GetCoderEffectiveMaxTokens()\n\t} else {\n\t\tlog.Printf(\"Tell plan - execTellPlan - unknown tell stage: %s\\n\", state.currentStage.TellStage)\n\t\tgo notify.NotifyErr(notify.SeverityError, fmt.Errorf(\"execTellPlan: unknown tell stage: %s\", state.currentStage.TellStage))\n\n\t\tactive.StreamDoneCh <- &shared.ApiError{\n\t\t\tType:   shared.ApiErrorTypeOther,\n\t\t\tStatus: http.StatusInternalServerError,\n\t\t\tMsg:    \"Unknown tell stage\",\n\t\t}\n\t\treturn\n\t}\n\n\tok, tokensWithoutContext := state.dryRunCalculateTokensWithoutContext(tentativeMaxTokens, unfinishedSubtaskReasoning)\n\tif !ok {\n\t\treturn\n\t}\n\n\tvar planStageSharedMsgs []*types.ExtendedChatMessagePart\n\tvar planningPhaseOnlyMsgs []*types.ExtendedChatMessagePart\n\tvar implementationMsgs []*types.ExtendedChatMessagePart\n","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/tell_exec.go#L178-L214","documentation":"execTellPlan selects the model and token budget based on state.currentStage.TellStage: context-loading stages use one model, TellStageImplementation uses the coder model. If the stage is neither of the known values, the code logs, reports, and sends a 500 ApiError with the static message \"Unknown tell stage\". It means the plan is in a TellStage value this executor does not handle — usually an out-of-date executor or corrupted stage state.","triggerScenarios":"state.currentStage.TellStage holds a value outside the handled set (e.g. an added TellStage enum value from a newer shared package running against an older executor, or an uninitialized/zero-value stage) when execTellPlan builds the tentative model config.","commonSituations":"Version skew between plandex-shared and plandex-server after a partial upgrade; a plan resumed with stage state persisted by a different version; a bug where the stage was never initialized before execTellPlan ran.","solutions":["Log/inspect state.currentStage.TellStage (printed in server logs) to see which unexpected value arrived.","Upgrade plandex-server and plandex-shared together so TellStage enums match across versions.","Reset the plan's stage state by re-issuing the tell request from the client rather than resuming stale state.","Extend the if/else chain to handle the new stage if you added a custom TellStage value."],"exampleFix":"// before\n} else if state.currentStage.TellStage == shared.TellStageImplementation {\n    tentativeModelConfig = state.settings.GetModelPack().GetCoder()\n} else { /* 500 Unknown tell stage */ }\n// after\n} else if state.currentStage.TellStage == shared.TellStageImplementation {\n    tentativeModelConfig = state.settings.GetModelPack().GetCoder()\n} else if state.currentStage.TellStage == shared.TellStageNewAdd {\n    tentativeModelConfig = state.settings.GetModelPack().GetWholeFileBuilder() // handle new stage\n} else { /* 500 */ }","handlingStrategy":"validation","validationCode":"switch stage := state.currentStage.TellStage; stage {\ncase shared.TellStageAuto, shared.TellStageImplementation, shared.TellStageNewAdd:\n    // supported, proceed with Tell\ndefault:\n    return fmt.Errorf(\"unsupported tell stage %q — upgrade server and shared module together\", stage)\n}","typeGuard":"func isKnownTellStage(s shared.TellStage) bool {\n    switch s {\n    case shared.TellStageAuto, shared.TellStageImplementation:\n        return true\n    }\n    return false\n}","tryCatchPattern":"apiErr := <-active.StreamDoneCh\nif apiErr.Msg == \"Unknown tell stage\" {\n    log.Printf(\"server does not handle this TellStage; check version skew and re-issue tell\")\n    return reissueTell(planId, branch) // resets stage state\n}","preventionTips":["Upgrade plandex-server and plandex-shared in the same deploy.","Never resume plans whose persisted stage state was written by a different version.","Initialize currentStage before calling execTellPlan.","Log the stage value at tell start to catch bad state early."],"tags":["go","state-machine","version-skew","enum"],"backgroundTag":"unhandled-enum-value","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"}