{"record":{"id":"a59fbbe266337c96","repo":"plandex-ai/plandex","slug":"error-updating-plan-tokens","errorCode":null,"errorMessage":"Error updating plan tokens: ","messagePattern":"Error updating plan tokens: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_context.go","lineNumber":426,"sourceCode":"\t\terr = repo.GitAddAndCommit(branchName, commitMsg)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error committing changes: %v\", err)\n\t\t}\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tlog.Printf(\"Error deleting contexts: %v\\n\", err)\n\t\thttp.Error(w, \"Error deleting contexts: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\terr = db.AddPlanContextTokens(planId, branchName, -removeTokens)\n\tif err != nil {\n\t\tlog.Printf(\"Error updating plan tokens: %v\\n\", err)\n\t\thttp.Error(w, \"Error updating plan tokens: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tres := shared.DeleteContextResponse{\n\t\tTokensRemoved: removeTokens,\n\t\tTotalTokens:   branch.ContextTokens - removeTokens,\n\t\tMsg:           commitMsg,\n\t}\n\n\tbytes, err := json.Marshal(res)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error marshalling response: %v\\n\", err)\n\t\thttp.Error(w, \"Error marshalling response: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully deleted contexts\")","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_context.go#L408-L444","documentation":"DeleteContextHandler returns this 500 when db.AddPlanContextTokens fails while subtracting the tokens of just-deleted contexts from the plan branch's token count. The contexts themselves were already removed and committed inside ExecRepoOperation, so the failure is in the follow-up token accounting write. The underlying database error is appended to the message and logged.","triggerScenarios":"A DELETE-context request removed contexts successfully, but the subsequent AddPlanContextTokens(planId, branchName, -removeTokens) call fails — typically because the plan/branch row was concurrently deleted or renamed, the database is down/unreachable, or the plans table write hits a lock/serialization conflict.","commonSituations":"Another client deleted the plan or branch between the context removal and the token update; Postgres connection pool exhaustion or outage; the branch name no longer matches a stored branch row; transient DB constraint or lock-timeout errors.","solutions":["Check the server log for the underlying AddPlanContextTokens error appended to this message","Verify the plan and branch still exist in the database (planId, branchName from the request)","Confirm the Postgres connection configured for the server is healthy and not exhausted","Retry the delete-context request; if it recurs, inspect plans/plan tokens table state for stale rows"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const res = await fetch(`${base}/plans/${planId}/contexts`, {method: 'DELETE'});\nif (res.status === 404) throw new Error('Plan or branch no longer exists — refresh before deleting contexts');","typeGuard":null,"tryCatchPattern":"for (let i = 0; i < 3; i++) {\n  try {\n    const res = await deletePlanContexts(planId, ids);\n    return res;\n  } catch (e) {\n    if (i === 2 || !/Error updating plan tokens/.test(e.message)) throw e;\n    await new Promise(r => setTimeout(r, 500 * 2 ** i));\n  }\n}","preventionTips":["Refresh plan/branch state immediately before deleting contexts to avoid acting on stale planIds","Serialize plan mutations per user/plan so concurrent deletes cannot remove the plan mid-operation","Monitor database connection pool saturation and set sane pool limits","Alert on the server-side log line 'Error updating plan tokens'"],"tags":["http-500","database","plans","token-accounting"],"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"}