{"record":{"id":"8c3fdb8a3faf63a5","repo":"kopia/kopia","slug":"unable-to-delete-policy","errorCode":null,"errorMessage":"unable to delete policy","messagePattern":"unable to delete policy","errorType":"http","errorClass":"internalServerError","httpStatus":500,"severity":"error","filePath":"internal/server/api_policies.go","lineNumber":121,"sourceCode":"\n\t\tresp.UpcomingSnapshotTimes = append(resp.UpcomingSnapshotTimes, st)\n\t\tnow = st.Add(1 * time.Second)\n\t}\n\n\treturn resp, nil\n}\n\nfunc handlePolicyDelete(ctx context.Context, rc requestContext) (any, *apiError) {\n\tif _, ok := rc.rep.(repo.RepositoryWriter); !ok {\n\t\treturn nil, repositoryNotWritableError()\n\t}\n\n\tsourceInfo := getSnapshotSourceFromURL(rc.req.URL)\n\n\tif err := repo.WriteSession(ctx, rc.rep, repo.WriteSessionOptions{\n\t\tPurpose: \"PolicyDelete\",\n\t}, func(ctx context.Context, w repo.RepositoryWriter) error {\n\t\treturn errors.Wrap(policy.RemovePolicy(ctx, w, sourceInfo), \"unable to delete policy\")\n\t}); err != nil {\n\t\treturn nil, internalServerError(err)\n\t}\n\n\trc.srv.Refresh()\n\n\treturn &serverapi.Empty{}, nil\n}\n\nfunc handlePolicyPut(ctx context.Context, rc requestContext) (any, *apiError) {\n\tnewPolicy := &policy.Policy{}\n\tif err := json.Unmarshal(rc.body, newPolicy); err != nil {\n\t\treturn nil, requestError(serverapi.ErrorMalformedRequest, \"malformed request body\")\n\t}\n\n\tif _, ok := rc.rep.(repo.RepositoryWriter); !ok {\n\t\treturn nil, repositoryNotWritableError()\n\t}","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/server/api_policies.go#L103-L139","documentation":"Kopia server API returns this 500 error when deleting a snapshot-source policy fails. The handler wraps policy.RemovePolicy (which reads the manifest and writes a delete of the policy manifest) inside a repo.WriteSession; any underlying storage, manifest, or validation error is re-wrapped with this message.","triggerScenarios":"DELETE /api/v1/policy with a source URL whose policy manifest cannot be loaded or written; repository write session fails (storage unavailable, read-only, concurrent write conflict); RemovePolicy encounters an invalid or already-deleted policy manifest.","commonSituations":"Blob storage (S3/B2/fs) credentials expired or network down; repository locked by another writer; policy manifest corrupted or already removed by another client; server connected read-only.","solutions":["Verify repository connectivity with `kopia repository status` and re-run the delete","Check storage backend credentials/network and retry","Confirm the policy still exists (`kopia policy list`) — it may have been deleted already","Retry after concurrent writers finish; manifest writes conflict-transiently"],"exampleFix":"// before\nreturn errors.Wrap(policy.RemovePolicy(ctx, w, sourceInfo), \"unable to delete policy\")\n// after\nerr := policy.RemovePolicy(ctx, w, sourceInfo)\nif errors.Is(err, manifest.ErrNotFound) {\n    return nil // treat as already-deleted, succeed idempotently\n}\nreturn errors.Wrap(err, \"unable to delete policy\")","handlingStrategy":"try-catch","validationCode":"// Go: ensure policy exists before deleting\npol, err := policy.GetDefinedPolicy(ctx, rep, src)\nif err != nil || pol == nil { /* nothing to delete; skip call */ }","typeGuard":null,"tryCatchPattern":"err := repo.WriteSession(ctx, rep, opts, func(ctx, w) error {\n    if err := policy.RemovePolicy(ctx, w, src); err != nil {\n        if errors.Is(err, manifest.ErrNotFound) { return nil }\n        return err\n    }\n    return nil\n})\nif err != nil { log.Warnf(\"policy delete failed: %v\", err) }","preventionTips":["Check policy existence before delete for idempotency","Monitor storage backend health before issuing manifest writes","Avoid concurrent policy mutations from multiple clients"],"tags":["kopia","policy","storage","api"],"backgroundTag":"database-write-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}