{"record":{"id":"cf00affd64f8e1c7","repo":"crowdsecurity/crowdsec","slug":"stage-s-extracted-from-s-doesn-t-exist-in-th","errorCode":null,"errorMessage":"stage '%s' extracted from '%s' doesn't exist in the hub","messagePattern":"stage '(.+?)' extracted from '(.+?)' doesn't exist in the hub","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubtest/parser.go","lineNumber":62,"sourceCode":"\treturn nil\n}\n\nfunc (t *HubTestItem) installParserCustomFrom(parser string, customPath string) (bool, error) {\n\t// we check if its a custom parser\n\tcustomParserPath := filepath.Join(customPath, parser)\n\tif _, err := os.Stat(customParserPath); os.IsNotExist(err) {\n\t\treturn false, nil\n\t}\n\n\tcustomParserPathSplit, customParserName := filepath.Split(customParserPath)\n\t// because path is parsers/<stage>/<author>/parser.yaml and we wan't the stage\n\tsplitPath := strings.Split(customParserPathSplit, string(os.PathSeparator))\n\tcustomParserStage := splitPath[len(splitPath)-3]\n\n\t// check if stage exist\n\thubStagePath := filepath.Join(t.HubPath, fmt.Sprintf(\"parsers/%s\", customParserStage))\n\tif _, err := os.Stat(hubStagePath); os.IsNotExist(err) {\n\t\treturn false, fmt.Errorf(\"stage '%s' extracted from '%s' doesn't exist in the hub\", customParserStage, hubStagePath)\n\t}\n\n\tstageDirDest := fmt.Sprintf(\"%s/parsers/%s/\", t.RuntimePath, customParserStage)\n\tif err := os.MkdirAll(stageDirDest, os.ModePerm); err != nil {\n\t\treturn false, fmt.Errorf(\"unable to create folder '%s': %w\", stageDirDest, err)\n\t}\n\n\tcustomParserDest := filepath.Join(stageDirDest, customParserName)\n\t// if path to parser exist, copy it\n\tif err := Copy(customParserPath, customParserDest); err != nil {\n\t\treturn false, fmt.Errorf(\"unable to copy custom parser '%s' to '%s': %w\", customParserPath, customParserDest, err)\n\t}\n\n\treturn true, nil\n}\n\nfunc (t *HubTestItem) installParserCustom(parser string) error {\n\tfor _, customPath := range t.CustomItemsLocation {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/hubtest/parser.go#L44-L80","documentation":"installParserCustomFrom expects custom parser files to live in a path where the third-from-last path segment is a stage name that exists in the hub (e.g. .../parsers/s00-raw/name.yaml). When the extracted stage directory does not exist under <HubPath>/parsers, the function refuses to install and returns this error.","triggerScenarios":"Calling installParserCustom with a custom parser path whose directory layout places a bogus/nonexistent stage two levels up (e.g. .../parsers/s02-unknown/my-parser.yaml) or a path with too few segments so the wrong segment is picked as the stage.","commonSituations":"Renaming or restructuring a custom parser directory without matching a real hub stage; typo in the stage name (s01-raw vs s00-raw); putting the parser file directly in runtime/parsers/ without a stage directory.","solutions":["Move/rename the custom parser so its parent structure is <path>/parsers/<existing-stage>/<name>.yaml with a stage that exists in the hub (`ls <HubPath>/parsers`).","Check the stage name spelling against hub stages (s00-raw, s01-parse, ...).","If it's not a custom parser but a hub item, use the normal installParser path instead."],"exampleFix":"// before\ncustom := \"./mytests/parsers/s05-typo/my.yaml\"\n// after\ncustom := \"./mytests/parsers/s01-parse/my.yaml\" // stage must exist in hub parsers/","handlingStrategy":"validation","validationCode":"stage := filepath.Base(filepath.Dir(filepath.Dir(customParserPath)))\nif _, err := os.Stat(filepath.Join(hubPath, \"parsers\", stage)); err != nil {\n\treturn fmt.Errorf(\"stage %s does not exist in hub; valid stages: %v\", stage, hubStages)\n}","typeGuard":null,"tryCatchPattern":"if err := item.InstallParserCustom(name); err != nil {\n\t// check the custom parser's directory layout matches <...>/parsers/<stage>/<file>.yaml\n\treturn err\n}","preventionTips":["Keep custom parsers under a directory named after an existing hub stage (s00-raw, s01-parse, ...).","Never place custom parser files directly under parsers/ without a stage directory.","Cross-check stage names with `ls <HubPath>/parsers`."],"tags":["hubtest","custom-parser","path-layout","stage"],"backgroundTag":"directory-not-found","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"}