{"record":{"id":"27e0dd5ef3d18ee4","repo":"goharbor/harbor","slug":"conflict","errorCode":"CONFLICT","errorMessage":"rule %d is conflict with rule %d","messagePattern":"rule (.+?) is conflict with rule (.+?)","errorType":"http","errorClass":"ConflictError","httpStatus":409,"severity":"error","filePath":"src/server/v2.0/handler/retention.go","lineNumber":242,"sourceCode":"\t}\n\n\tif err := r.requirePolicyAccess(ctx, p); err != nil {\n\t\treturn r.SendError(ctx, err)\n\t}\n\n\tif err := r.retentionCtl.UpdateRetention(ctx, p); err != nil {\n\t\treturn r.SendError(ctx, err)\n\t}\n\treturn operation.NewUpdateRetentionOK()\n}\n\nfunc (r *retentionAPI) checkRuleConflict(p *policy.Metadata) error {\n\ttemp := make(map[string]int)\n\tfor n, rule := range p.Rules {\n\t\trule.ID = 0\n\t\tbs, _ := json.Marshal(rule)\n\t\tif old, exists := temp[string(bs)]; exists {\n\t\t\treturn fmt.Errorf(\"rule %d is conflict with rule %d\", n, old)\n\t\t}\n\t\ttemp[string(bs)] = n\n\t\trule.ID = n\n\t}\n\treturn nil\n}\n\nfunc (r *retentionAPI) DeleteRetention(ctx context.Context, params operation.DeleteRetentionParams) middleware.Responder {\n\tp, err := r.retentionCtl.GetRetention(ctx, params.ID)\n\tif err != nil {\n\t\treturn r.SendError(ctx, errors.BadRequestError(err))\n\t}\n\terr = r.requireAccess(ctx, p, rbac.ActionDelete)\n\tif err != nil {\n\t\treturn r.SendError(ctx, err)\n\t}\n\n\tif err = r.retentionCtl.DeleteRetention(ctx, params.ID); err != nil {","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/server/v2.0/handler/retention.go#L224-L260","documentation":"Duplicate-rule detector in checkRuleConflict (used by both create and update retention endpoints): each rule is serialized to JSON (with its ID zeroed) and used as a map key; if an identical rule body was already seen, the new rule conflicts with the earlier one and the policy is rejected. Two rules are 'the same' when every configured field except the ID matches.","triggerScenarios":"Thrown at src/server/v2.0/handler/retention.go:242 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove the duplicated rule — an identical rule adds nothing over the first copy","If near-duplicates were intended, differentiate them by repository selector, tag selector, scope level, or parameters","Review the whole rules array for copies before resubmitting"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","contentChangedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}