{"record":{"id":"79c1a27a96c4332a","repo":"kopia/kopia","slug":"acl-entry-for-a-given-user-and-target-already-exis","errorCode":null,"errorMessage":"ACL entry for a given user and target already exists %v: %v","messagePattern":"ACL entry for a given user and target already exists (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/acl/acl_manager.go","lineNumber":126,"sourceCode":"\n\treturn result, nil\n}\n\n// AddACL validates and adds the specified ACL entry to the repository.\nfunc AddACL(ctx context.Context, w repo.RepositoryWriter, e *Entry, overwrite bool) error {\n\tif err := e.Validate(); err != nil {\n\t\treturn errors.Wrap(err, \"error validating ACL\")\n\t}\n\n\tentries, err := LoadEntries(ctx, w, nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"unable to load ACL entries\")\n\t}\n\n\tfor _, oldE := range entries {\n\t\tif e.User == oldE.User && maps.Equal(e.Target, oldE.Target) {\n\t\t\tif !overwrite && e.Access < oldE.Access {\n\t\t\t\treturn errors.Errorf(\"ACL entry for a given user and target already exists %v: %v\", oldE.User, oldE.Target)\n\t\t\t}\n\n\t\t\tif err = w.DeleteManifest(ctx, oldE.ManifestID); err != nil {\n\t\t\t\treturn errors.Wrap(err, \"error deleting old\")\n\t\t\t}\n\t\t}\n\t}\n\n\tmanifestID, err := w.PutManifest(ctx, map[string]string{\n\t\tmanifest.TypeLabelKey: aclManifestType,\n\t}, e)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error writing manifest\")\n\t}\n\n\te.ManifestID = manifestID\n\n\treturn nil","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/acl/acl_manager.go#L108-L144","documentation":"AddACL found an existing entry with the same user and target, and the requested entry's access level is lower than the existing one while overwrite=false. To avoid silently downgrading permissions, the operation is refused. Set overwrite=true to replace the entry regardless.","triggerScenarios":"Calling AddACL without overwrite for a (User, Target) pair that already exists with a higher access level, e.g. adding a 'read' ACL for a user who already has 'write' on the same target.","commonSituations":"Re-running an ACL provisioning script after permissions were raised; assuming AddACL upserts by default; conflicting ACLs created by two administrators.","solutions":["Pass overwrite=true to AddACL (or the appropriate CLI flag) to replace the existing entry","Remove the existing ACL entry first, then add the new one","Choose an equal or higher access level if the downgrade was unintentional"],"exampleFix":"// before\nAddACL(ctx, rep, entry, false)\n// after\nAddACL(ctx, rep, entry, true)","handlingStrategy":"validation","validationCode":"entries, _ := acl.LoadEntries(ctx, rep, nil)\nfor _, e := range entries {\n    if e.User == newUser && maps.Equal(e.Target, newTarget) && newEntry.Access < e.Access {\n        return fmt.Errorf(\"would downgrade %s; pass overwrite=true intentionally\", newUser)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["List existing ACLs with 'kopia acl list' before adding entries","Make overwrite an explicit, audited decision in automation","Detect duplicate (user, target) pairs in provisioning scripts"],"tags":["acl","conflict","go"],"backgroundTag":"file-already-exists","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"}