{"record":{"id":"57cf8a2c19047ec8","repo":"plandex-ai/plandex","slug":"error-deleting-draft-plans-v","errorCode":null,"errorMessage":"error deleting draft plans: %v","messagePattern":"error deleting draft plans: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/plan_helpers.go","lineNumber":355,"sourceCode":"\tbytes, err := json.Marshal(description)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling convo message description: %v\", err)\n\t}\n\n\terr = os.WriteFile(filepath.Join(descriptionsDir, description.Id+\".json\"), bytes, os.ModePerm)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing convo message description: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc DeleteDraftPlans(orgId, projectId, userId string) error {\n\tres, err := Conn.Query(\"DELETE FROM plans WHERE project_id = $1 AND owner_id = $2 AND name = 'draft' RETURNING id;\", projectId, userId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error deleting draft plans: %v\", err)\n\t}\n\n\tdefer res.Close()\n\n\t// get ids\n\tvar ids []string\n\n\tfor res.Next() {\n\t\tvar id string\n\t\terr := res.Scan(&id)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error scanning deleted draft plan id: %v\", err)\n\t\t}\n\t\tids = append(ids, id)\n\t}\n\n\terrCh := make(chan error, len(ids))\n\tfor _, planId := range ids {","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/plan_helpers.go#L337-L373","documentation":"DeleteDraftPlans removes all plans named 'draft' for a project+owner and returns their ids. This error wraps a failure of the DELETE ... RETURNING query itself, meaning the database refused or could not execute the statement (connection issue, SQL error).","triggerScenarios":"Conn.Query(\"DELETE FROM plans WHERE project_id = $1 AND owner_id = $2 AND name = 'draft' RETURNING id;\", ...) fails: connection to Postgres dropped, table missing after migration drift, syntax/type mismatch, or DB timeout.","commonSituations":"DB connection pool exhausted; schema migration out of sync (plans table or columns missing); network blip between app and database; using a closed global Conn after failed reconnect.","solutions":["Check the wrapped driver error for the exact Postgres failure","Verify DB connectivity and connection-pool limits","Confirm schema migrations ran (plans table, project_id/owner_id columns exist)","Enable driver-level retry/reconnect on transient connection errors"],"exampleFix":"// before\nif err != nil {\n    return fmt.Errorf(\"error deleting draft plans: %v\", err)\n}\n// after\nif err != nil {\n    return fmt.Errorf(\"error deleting draft plans: %w\", err)\n}","handlingStrategy":"retry","validationCode":"if err := db.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := DeleteDraftPlans(orgId, projectId, userId)\nif err != nil {\n    if isTransientDBError(err) { // net.Error, driver.ErrBadConn\n        err = retry(3, func() error { return DeleteDraftPlans(orgId, projectId, userId) })\n    }\n    return err\n}","preventionTips":["Keep migrations in sync with deployed code","Use database/sql retry on driver.ErrBadConn","Monitor connection-pool saturation","Verify DELETE privileges for the app DB role"],"tags":["database","postgres","sql","delete"],"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"}