{"record":{"id":"6af2f55070b1da63","repo":"crowdsecurity/crowdsec","slug":"s-s-has-no-download-path","errorCode":null,"errorMessage":"%s:%s has no download path","messagePattern":"(.+?):(.+?) has no download path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cwhub/hub.go","lineNumber":90,"sourceCode":"\tbidx, err := os.ReadFile(h.local.HubIndexFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to read index file: %w\", err)\n\t}\n\n\tif err := json.Unmarshal(bidx, &h.items); err != nil {\n\t\treturn fmt.Errorf(\"failed to parse index: %w\", err)\n\t}\n\n\t// Iterate over the different types to complete the struct\n\tfor _, itemType := range ItemTypes {\n\t\tfor name, item := range h.GetItemMap(itemType) {\n\t\t\tif item == nil {\n\t\t\t\t// likely defined as empty object or null in the index file\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no index metadata\", itemType, name)\n\t\t\t}\n\n\t\t\tif item.RemotePath == \"\" {\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no download path\", itemType, name)\n\t\t\t}\n\n\t\t\tif (itemType == PARSERS || itemType == POSTOVERFLOWS) && item.Stage == \"\" {\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no stage\", itemType, name)\n\t\t\t}\n\n\t\t\titem.hub = h\n\t\t\titem.Name = name\n\n\t\t\titem.Type = itemType\n\t\t\titem.FileName = path.Base(item.RemotePath)\n\n\t\t\titem.logMissingSubItems()\n\n\t\t\tif item.latestHash() == \"\" {\n\t\t\t\th.logger.Errorf(\"invalid hub item %s: latest version missing from index\", item.FQName())\n\t\t\t}\n\t\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/cwhub/hub.go#L72-L108","documentation":"During hub index parsing (parseIndex, invoked by Hub.Load), every index entry must declare a RemotePath pointing to its upstream download location. If the entry exists but has an empty RemotePath, the hub cannot ever fetch it, so loading aborts. This protects against corrupt or hand-edited .index.json files.","triggerScenarios":"Calling Hub.Load() when the hub index file contains an entry for an item whose RemotePath field is empty, typically because the index was manually edited, truncated, or produced by a broken taint/update run.","commonSituations":"Hand-editing or regenerating the local .index.json; a failed `cscli hub update` leaving partial index entries; copying an index from another hub installation; syncing the hub directory with an incomplete file.","solutions":["Re-run `cscli hub update` to regenerate a fresh index from the upstream hub","Restore the .index.json file (delete it and let crowdsec re-download it)","If authoring index entries, ensure each item sets RemotePath to its repo-relative path in the hub repository","Check disk space / permissions if index writes were truncated"],"exampleFix":"// before (index entry)\n\"crowdsecurity/http-logs\": {\"name\":\"http-logs\",\"remote_path\":\"\"}\n// after\n\"crowdsecurity/http-logs\": {\"name\":\"http-logs\",\"remote_path\":\"parsers/s01-bench/crowdsecurity/http-logs.yaml\"}","handlingStrategy":"validation","validationCode":"if item == nil || item.RemotePath == \"\" {\n    return fmt.Errorf(\"skipping index entry %s:%s: missing remote path\", itemType, name)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-edit .index.json; use cscli hub update","Back up the hub index before scripted modifications","Validate index JSON against expected fields before loading"],"tags":["hub","config","index"],"backgroundTag":"missing-required-config-field","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"}