{"record":{"id":"3187e7f5e9705a9f","repo":"plandex-ai/plandex","slug":"err-error-3187e7","errorCode":null,"errorMessage":"err.Error()","messagePattern":"err\\.Error\\(\\)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_crud.go","lineNumber":487,"sourceCode":"\t\t\t\tlog.Printf(\"panic in ListPlansRunningHandler: %v\\n%s\", r, debug.Stack())\n\t\t\t\terrCh <- fmt.Errorf(\"panic in ListPlansRunningHandler: %v\\n%s\", r, debug.Stack())\n\t\t\t\truntime.Goexit() // don't allow outer function to continue and double-send to channel\n\t\t\t}\n\t\t}()\n\t\tvar err error\n\t\tbranches, err = db.ListBranchesForPlans(auth.OrgId, planIds)\n\t\tif err != nil {\n\t\t\terrCh <- fmt.Errorf(\"error getting branches: %v\", err)\n\t\t\treturn\n\t\t}\n\t\terrCh <- nil\n\t}()\n\n\tfor i := 0; i < 2; i++ {\n\t\terr := <-errCh\n\t\tif err != nil {\n\t\t\tlog.Println(err)\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t}\n\n\tres := shared.ListPlansRunningResponse{\n\t\tBranches:                   []*shared.Branch{},\n\t\tStreamStartedAtByBranchId:  map[string]time.Time{},\n\t\tStreamFinishedAtByBranchId: map[string]time.Time{},\n\t\tPlansById:                  map[string]*shared.Plan{},\n\t\tStreamIdByBranchId:         map[string]string{},\n\t}\n\n\tvar apiPlansById = make(map[string]*shared.Plan)\n\tfor _, plan := range plans {\n\t\tapiPlan := plan.ToApi()\n\t\tapiPlansById[plan.Id] = apiPlan\n\t}\n","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_crud.go#L469-L505","documentation":"This is a generic 500 returned by ListPlansRunningHandler when one of two parallel goroutines fails: either fetching active/recent model streams (GetActiveOrRecentModelStreams / GetActiveModelStreams) or fetching branches (ListBranchesForPlans). The handler collects results over an errCh channel and surfaces the first non-nil error verbatim to the client. The message text is the wrapped Go error, so it will name the failing DB query (e.g. 'error getting recent model streams: ...' or 'error getting branches: ...'), or a panic recovered inside a goroutine.","triggerScenarios":"Calling GET list-plans-running while the database query for streams or branches fails (connection drop, timeout, bad SQL, transient Postgres error), or one of the goroutines panics (nil deref, etc.) and the deferred recover sends a wrapped panic error to errCh.","commonSituations":"Postgres restarts or connection-pool exhaustion under load; slow queries hitting a statement timeout; schema drift after a migration making ListBranchesForPlans fail; a bug causing a nil-pointer panic inside one of the goroutines.","solutions":["Read the server log line printed just before the response (log.Println(err)) — it contains the underlying database error; fix the root cause there","Check DB connectivity/health (pool exhaustion, max_connections, timeouts) and retry the request","If a panic was logged with a stack trace, fix the nil-dereference or bug in the goroutine that panicked","If it persists, verify the DB schema matches the sqlx struct tags for ModelStream and Branch after recent migrations"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight DB health check before calling the endpoint\nif err := db.Conn.Ping(); err != nil {\n    return fmt.Errorf(\"database unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// Go: check status and error body, retry transient failures with backoff\nresp, err := client.Get(listPlansRunningURL)\nif err != nil { return err }\nif resp.StatusCode == http.StatusInternalServerError {\n    body, _ := io.ReadAll(resp.Body)\n    return retryWithBackoff(3, func() error { return callListPlansRunning() })\n}","preventionTips":["Monitor DB connectivity and pool saturation; alert before pool exhaustion","Set sane query timeouts so slow stream/branch queries fail fast and retriable","Keep DB schema migrations in sync with the sqlx struct definitions","Cover ListPlansRunningHandler with an integration test against a real test database"],"tags":["go","http","database","internal-server-error"],"backgroundTag":"database-query-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"}