{"record":{"id":"6ac1eb8fd421788d","repo":"crowdsecurity/crowdsec","slug":"s-w-6ac1eb","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cwhub/sync.go","lineNumber":156,"sourceCode":"\ttargetInHub, err := isPathInside(spec.target, hubDir)\n\tif err != nil {\n\t\treturn nil, ErrSkipPath\n\t}\n\n\tspec.local = !targetInHub\n\n\treturn spec, nil\n}\n\n// sortedVersions returns the input data, sorted in reverse order (new, old) by semver.\nfunc sortedVersions(raw []string) ([]string, error) {\n\tvs := make([]*semver.Version, len(raw))\n\n\tfor idx, r := range raw {\n\t\tv, err := semver.NewVersion(r)\n\t\tif err != nil {\n\t\t\t// TODO: should catch this during index parsing\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", r, err)\n\t\t}\n\n\t\tvs[idx] = v\n\t}\n\n\tsort.Sort(sort.Reverse(semver.Collection(vs)))\n\n\tret := make([]string, len(vs))\n\tfor idx, v := range vs {\n\t\tret[idx] = v.Original()\n\t}\n\n\treturn ret, nil\n}\n\nfunc newLocalItem(h *Hub, path string, spec *itemSpec) (*Item, error) {\n\ttype localItemName struct {\n\t\tName string `yaml:\"name\"`","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/cwhub/sync.go#L138-L174","documentation":"sortedVersions converts raw version strings from a hub item's version metadata into semver.Version values so it can sort them newest-first. If any string is not valid semantic version (semver.NewVersion fails), sorting cannot proceed and the raw string is wrapped into this error. detectVersionFromHash calls it when matching an installed file's hash against known item versions.","triggerScenarios":"A hub index entry contains a version tag that is not valid semver (e.g. '1.0', 'v1-', a branch name like 'master', or a typo like '1..2'), and localSync/detectVersionFromHash tries to sort that item's versions.","commonSituations":"Out-of-tree or hand-edited hub index (.index.json) with non-semver version fields; custom/private hubtacks whose authors used loose version labels; upstream hub metadata change not handled by the local crowdsec version.","solutions":["Run 'cscli hub update' (and 'cscli hub upgrade') to get a corrected index from upstream","Inspect the item's versions in the hub index file and fix any non-semver tag to a valid MAJOR.MINOR.PATCH form","If it's a custom hub, republish the item metadata with semver-compliant version strings"],"exampleFix":"// before: item in .index.json\n\"version\": \"latest\"\n// after\n\"version\": \"1.0.0\"","handlingStrategy":"validation","validationCode":"import \"golang.org/x/mod/semver\"\n\nfunc allSemver(tags []string) error {\n\tfor _, t := range tags {\n\t\tv := strings.TrimPrefix(t, \"v\")\n\t\tparts := strings.Split(v, \".\")\n\t\tif len(parts) != 3 {\n\t\t\treturn fmt.Errorf(\"%q is not MAJOR.MINOR.PATCH\", t)\n\t\t}\n\t}\n\treturn nil\n}\n// run against the item's versions before enabling a custom hub","typeGuard":null,"tryCatchPattern":"if err := hub.Load(ctx); err != nil {\n\tvar badVer string\n\tif matchesInvalidVersion(err, &badVer) {\n\t\treturn fmt.Errorf(\"hub index has non-semver version %q; run 'cscli hub update'\", badVer)\n\t}\n\treturn err\n}","preventionTips":["Never hand-edit .index.json version fields","In custom hubtacks, always tag items with valid semver (1.2.3), not 'latest' or branch names","Keep crowdsec and the hub index updated together via cscli hub update/upgrade"],"tags":["hub","semver","versioning","metadata","crowdsec"],"backgroundTag":"invalid-version-format","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}