{"record":{"id":"2f90828e16e5ce68","repo":"crowdsecurity/crowdsec","slug":"circular-dependency-detected-s-depends-on-s","errorCode":null,"errorMessage":"circular dependency detected: %s depends on %s","messagePattern":"circular dependency detected: (.+?) depends on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cwhub/item.go","lineNumber":351,"sourceCode":"\n// descendants returns a list of all (direct or indirect) dependencies of the item's current version.\nfunc (i *Item) descendants() ([]*Item, error) {\n\tvar collectSubItems func(item *Item, visited map[*Item]bool, result *[]*Item) error\n\n\tcollectSubItems = func(item *Item, visited map[*Item]bool, result *[]*Item) error {\n\t\tif item == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tif visited[item] {\n\t\t\treturn nil\n\t\t}\n\n\t\tvisited[item] = true\n\n\t\tfor subItem := range item.CurrentDependencies().SubItems(item.hub) {\n\t\t\tif subItem == i {\n\t\t\t\treturn fmt.Errorf(\"circular dependency detected: %s depends on %s\", item.Name, i.Name)\n\t\t\t}\n\n\t\t\t*result = append(*result, subItem)\n\n\t\t\terr := collectSubItems(subItem, visited, result)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tret := []*Item{}\n\tvisited := map[*Item]bool{}\n\n\terr := collectSubItems(i, visited, &ret)\n\tif err != nil {","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/cwhub/item.go#L333-L369","documentation":"When expanding an item's dependency tree (collectSubItems), the traversal detects that a sub-item's dependency chain loops back to the item being expanded. Since collections can include other collections, a cycle would recurse forever, so it's reported as an error naming the two items involved.","triggerScenarios":"Creating a collection that (transitively) includes itself — e.g. collection A includes collection B which includes A; hit while computing dependencies/sub-items for install, taint, or upgrade operations.","commonSituations":"Authoring a custom collection YAML that re-includes its own name; editing a hub collection locally to reference itself; merging collection definitions incorrectly.","solutions":["Remove the self-referencing include from the collection YAML","Redesign the dependency so the cycle is broken (split into two collections)","Check `cscli hub list --all` / dependency output to trace which item re-includes which"],"exampleFix":"// before (collections/my-collection.yaml)\ninclude:\n  - my-collection   # circular\n// after\ninclude:\n  - crowdsecurity/ssh-bf\n  - crowdsecurity/http-cve","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"deps, err := item.SubItems() // or the collect API in use\nif err != nil {\n    if strings.Contains(err.Error(), \"circular dependency\") {\n        return fmt.Errorf(\"fix collection YAML: %w\", err)\n    }\n    return err\n}","preventionTips":["Never include a collection in itself, directly or transitively","Draw the dependency graph of custom collections before publishing","Keep custom collections leaf-only (include only stock hub items)"],"tags":["hub","dependencies","cycle"],"backgroundTag":"circular-dependency-detected","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}