{"record":{"id":"429efa72b610a50c","repo":"plandex-ai/plandex","slug":"error-removing-contexts-v","errorCode":null,"errorMessage":"error removing contexts: %v","messagePattern":"error removing contexts: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_context.go","lineNumber":398,"sourceCode":"\t\tClearRepoOnErr: true,\n\t}, func(repo *db.GitRepo) error {\n\t\tvar err error\n\t\tdbContexts, err = db.GetPlanContexts(auth.OrgId, planId, false, false)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error getting contexts: %v\", err)\n\t\t}\n\n\t\tfor _, dbContext := range dbContexts {\n\t\t\tif _, ok := requestBody.Ids[dbContext.Id]; ok {\n\t\t\t\ttoRemove = append(toRemove, dbContext)\n\t\t\t}\n\t\t}\n\n\t\terr = db.ContextRemove(auth.OrgId, planId, toRemove)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error removing contexts: %v\", err)\n\t\t}\n\n\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","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_context.go#L380-L416","documentation":"Returned by DeleteContextHandler when db.ContextRemove(auth.OrgId, planId, toRemove) fails after contexts were fetched and filtered. The DB deletion of the selected context rows failed (toRemove may be empty if no requested IDs matched, which some storage layers reject); the wrapped error is surfaced as HTTP 500 'Error deleting contexts'.","triggerScenarios":"Deleting contexts whose IDs were found via GetPlanContexts but whose DB removal then fails — storage-layer delete error, transaction failure, or calling ContextRemove with an empty toRemove slice because none of requestBody.Ids matched existing contexts.","commonSituations":"Client sending stale/unknown context IDs so toRemove is empty; concurrent deletion by another session; DB constraint or connection errors.","solutions":["Log/inspect the wrapped DB error from ContextRemove","Validate requestBody.Ids against existing contexts and return early when toRemove is empty","Check for concurrent deletes and unique/foreign-key constraint violations","Retry transient DB failures"],"exampleFix":"// before\nerr = db.ContextRemove(auth.OrgId, planId, toRemove)\nif err != nil {\n    return fmt.Errorf(\"error removing contexts: %v\", err)\n}\n// after\nif len(toRemove) == 0 {\n    return nil // nothing matched requestBody.Ids; skip remove + commit\n}\nif err := db.ContextRemove(auth.OrgId, planId, toRemove); err != nil {\n    return fmt.Errorf(\"error removing contexts: %w\", err)\n}","handlingStrategy":"validation","validationCode":"toRemove := make([]*db.Context, 0)\nfor _, dbContext := range dbContexts {\n    if _, ok := requestBody.Ids[dbContext.Id]; ok {\n        toRemove = append(toRemove, dbContext)\n    }\n}\nif len(toRemove) == 0 {\n    return errors.New(\"no matching contexts found for requested ids\")\n}","typeGuard":null,"tryCatchPattern":"if err := db.ContextRemove(auth.OrgId, planId, toRemove); err != nil {\n    return fmt.Errorf(\"error removing contexts: %w\", err)\n}\n// caller: inspect wrapped cause; on constraint errors refresh context list and retry once","preventionTips":["Validate requested IDs against existing contexts and no-op on empty match","Handle concurrent deletions by refreshing the context list","Check DB constraint errors explicitly for clearer client messages"],"tags":["go","database","context-management"],"backgroundTag":"database-delete-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"}