{"record":{"id":"5523b3fa8392c4bf","repo":"plandex-ai/plandex","slug":"error-setting-plan-status-to-replying-v","errorCode":null,"errorMessage":"Error setting plan status to replying: %v","messagePattern":"Error setting plan status to replying: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/model/plan/tell_exec.go","lineNumber":143,"sourceCode":"\t\tlog.Println(\"Executing WillExecPlanHook\")\n\t\t_, apiErr := hooks.ExecHook(hooks.WillExecPlan, hooks.HookParams{\n\t\t\tAuth: auth,\n\t\t\tPlan: plan,\n\t\t})\n\n\t\tif apiErr != nil {\n\t\t\ttime.Sleep(100 * time.Millisecond)\n\t\t\tactive.StreamDoneCh <- apiErr\n\t\t\treturn\n\t\t}\n\t}\n\n\tplanId := plan.Id\n\tlog.Println(\"execTellPlan - Setting plan status to replying\")\n\terr := db.SetPlanStatus(planId, branch, shared.PlanStatusReplying, \"\")\n\tif err != nil {\n\t\tlog.Printf(\"Error setting plan %s status to replying: %v\\n\", planId, err)\n\t\tgo notify.NotifyErr(notify.SeverityError, fmt.Errorf(\"error setting plan %s status to replying: %v\", planId, err))\n\n\t\tactive.StreamDoneCh <- &shared.ApiError{\n\t\t\tType:   shared.ApiErrorTypeOther,\n\t\t\tStatus: http.StatusInternalServerError,\n\t\t\tMsg:    fmt.Sprintf(\"Error setting plan status to replying: %v\", err),\n\t\t}\n\n\t\tlog.Printf(\"execTellPlan: execTellPlan operation completed for plan ID %s on branch %s, iteration %d\\n\", plan.Id, branch, iteration)\n\t\treturn\n\t}\n\tlog.Println(\"execTellPlan - Plan status set to replying\")\n\n\tstate := &activeTellStreamState{\n\t\tmodelStreamId:       active.ModelStreamId,\n\t\tclients:             clients,\n\t\tauthVars:            authVars,\n\t\treq:                 req,\n\t\tauth:                auth,","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/tell_exec.go#L125-L161","documentation":"At the start of execTellPlan the plan status is persisted as PlanStatusReplying via db.SetPlanStatus(planId, branch, ...). If that DB update fails, the error is logged, reported, and pushed to StreamDoneCh as a 500 ApiError \"Error setting plan status to replying: %v\". The plan cannot stream a reply because its persisted status could not transition.","triggerScenarios":"db.SetPlanStatus returns an error when execTellPlan (invoked from Tell, handleStreamFinished, or handleMissingFile) begins: DB unreachable, plan row missing (e.g. plan deleted while starting), lock contention, or invalid planId/branch combination.","commonSituations":"Database outage or connection-pool exhaustion at request start; user deleted/re-created the plan or branch concurrently; replica/leader DB failover mid-request; schema migration mismatch after upgrading Plandex.","solutions":["Read the wrapped error in server logs to identify the DB failure mode and fix connectivity/migrations.","Confirm the plan row and branch still exist in the DB (plan may have been deleted concurrently).","Retry the tell request after the DB is healthy — the status write is retried per invocation.","Check DB lock/timeout settings if this appears under concurrent stop/start load on the same plan."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify DB reachable and plan exists before issuing Tell\nif err := db.HealthCheck(); err != nil {\n    return fmt.Errorf(\"db unavailable: %w\", err)\n}\nif _, err := db.GetPlan(planId); err != nil {\n    return fmt.Errorf(\"plan %s not found: %w\", planId, err)\n}","typeGuard":null,"tryCatchPattern":"apiErr := <-active.StreamDoneCh\nif strings.Contains(apiErr.Msg, \"Error setting plan status to replying\") {\n    // transient DB failure: retry after backoff, plan was never set to replying\n    time.Sleep(2 * time.Second)\n    return retryTell(planId, branch)\n}","preventionTips":["Check DB health/limits before starting long plan operations.","Do not delete a plan or branch while a tell request is starting.","Ensure migrations are current after upgrading Plandex.","Retry idempotently: status setting is safe to re-attempt once the DB recovers."],"tags":["go","database","plan-status","persistence"],"backgroundTag":"database-write-failed","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"}