{"record":{"id":"b03071307cfd20d0","repo":"plandex-ai/plandex","slug":"error-deleting-contexts","errorCode":null,"errorMessage":"Error deleting contexts: ","messagePattern":"Error deleting contexts: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_context.go","lineNumber":419,"sourceCode":"\t\tfor _, dbContext := range toRemove {\n\t\t\ttoRemoveApiContexts = append(toRemoveApiContexts, dbContext.ToApi())\n\t\t\tremoveTokens += dbContext.NumTokens\n\t\t}\n\n\t\tcommitMsg = shared.SummaryForRemoveContext(toRemoveApiContexts, branch.ContextTokens) + \"\\n\\n\" + shared.TableForRemoveContext(toRemoveApiContexts)\n\n\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","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_context.go#L401-L437","documentation":"The delete operation wrapped in db.ExecRepoOperation inside DeleteContextHandler returned an error, so the handler responds with HTTP 500. The callback fetches plan contexts, removes the requested ones via db.ContextRemove, and commits with repo.GitAddAndCommit — any of these failing (or the lock/ExecRepoOperation itself) surfaces here, and ClearRepoOnErr resets the repo.","triggerScenarios":"db.GetPlanContexts fails, db.ContextRemove fails (rows already deleted, DB error), or repo.GitAddAndCommit fails (stale index.lock, conflict, disk full) inside the write-locked callback; ExecRepoOperation's lock/cancel handling can also return an error that lands on this check.","commonSituations":"Deleting context IDs that another session already deleted; concurrent writers contending on the repo lock; leftover .git/index.lock after a crash; branch deleted mid-request; DB/storage outages.","solutions":["Read the wrapped error text ('error getting contexts', 'error removing contexts', 'error committing changes') to identify the failing step","Refresh the plan's context list and drop already-deleted IDs from the request","Remove a stale .git/index.lock in the plan repo if a crashed writer left one","Retry after resolving concurrent-writer conflicts; the repo was already cleared on error","Check DB connectivity and disk space for the plan storage backend"],"exampleFix":"// before\ndbContexts, err = db.GetPlanContexts(auth.OrgId, planId, false, false)\nif err != nil {\n    return fmt.Errorf(\"error getting contexts: %v\", err)\n}\n// after\ndbContexts, err = db.GetPlanContexts(auth.OrgId, planId, false, false)\nif err != nil {\n    return fmt.Errorf(\"error getting contexts: %w\", err)\n}\n// also: filter requestBody.Ids to ids still present in dbContexts before ContextRemove","handlingStrategy":"fallback","validationCode":"// before deleting, verify all requested IDs still exist\ncurrent, err := listContexts(planId, branchName)\nif err != nil { return err }\nfor id := range req.Ids {\n    if !hasContext(current, id) {\n        delete(req.Ids, id) // skip already-deleted contexts\n    }\n}","typeGuard":null,"tryCatchPattern":"resp, err := sendDelete(req)\nif err != nil && resp != nil && resp.StatusCode == 500 {\n    // repo cleared on error; refresh state and retry once with surviving IDs\n    if err := refreshPlanState(planId, branchName); err != nil {\n        return err\n    }\n    return retryOnce(req)\n}","preventionTips":["Refresh context IDs immediately before deleting to skip already-removed ones","Serialize deletions per plan branch to avoid lock contention","Monitor and clean stale .git/index.lock files","Keep DB backups/health checks for the plan storage backend"],"tags":["http","go","git","database","server","internal-error"],"backgroundTag":"repo-operation-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"}