{"record":{"id":"3b78fe7ccea5422b","repo":"crowdsecurity/crowdsec","slug":"unable-to-symlink-parser-s-to-s-w","errorCode":null,"errorMessage":"unable to symlink parser '%s' to '%s': %w","messagePattern":"unable to symlink parser '(.+?)' to '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubtest/parser.go","lineNumber":40,"sourceCode":"\n\t// runtime/parsers/s00-raw/\n\titemTypeDirDest := fmt.Sprintf(\"%s/parsers/%s/\", t.RuntimePath, item.Stage)\n\n\tif err := createDirs([]string{hubDirParserDest, itemTypeDirDest}); err != nil {\n\t\treturn err\n\t}\n\n\t// runtime/hub/parsers/s00-raw/crowdsecurity/syslog-logs.yaml\n\thubDirParserPath := filepath.Join(hubDirParserDest, sourceFilename)\n\tif err := Copy(sourcePath, hubDirParserPath); err != nil {\n\t\treturn fmt.Errorf(\"unable to copy '%s' to '%s': %w\", sourcePath, hubDirParserPath, err)\n\t}\n\n\t// runtime/parsers/s00-raw/syslog-logs.yaml\n\tparserDirParserPath := filepath.Join(itemTypeDirDest, sourceFilename)\n\tif err := os.Symlink(hubDirParserPath, parserDirParserPath); err != nil {\n\t\tif !os.IsExist(err) {\n\t\t\treturn fmt.Errorf(\"unable to symlink parser '%s' to '%s': %w\", hubDirParserPath, parserDirParserPath, err)\n\t\t}\n\t}\n\n\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","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/hubtest/parser.go#L22-L58","documentation":"installParserItem creates a symlink in runtime/parsers/<stage>/ pointing to the hub copy; if os.Symlink fails with anything other than os.IsExist, it wraps the error. Typical causes are the destination parent directory missing or a filesystem that does not support symlinks.","triggerScenarios":"os.Symlink(hubDirParserPath, parserDirParserPath) returning an error other than EEXIST: parent dir runtime/parsers/<stage>/ not created, Windows without symlink privilege, stale non-symlink file at the destination path, permission denied.","commonSituations":"Running hubtests on Windows without developer mode/SeCreateSymbolicLinkPrivilege; a previous failed run left a regular file where the symlink goes; runtime tree partially deleted.","solutions":["Remove the conflicting file at the destination and re-run: `rm runtime/parsers/<stage>/<parser>.yaml`.","On Windows, enable Developer Mode or run the test with symlink privileges.","Recreate the runtime tree so installParser creates all parent directories fresh.","Verify the hub source path exists before symlinking (the copy step succeeded)."],"exampleFix":"// before\nos.RemoveAll(runtimePath) // leaves stale files if it fails silently\nrunParserTests()\n// after\nif err := os.RemoveAll(runtimePath); err != nil {\n\treturn fmt.Errorf(\"could not clean runtime dir: %w\", err)\n}\nrunParserTests()","handlingStrategy":"validation","validationCode":"dst := filepath.Join(runtimePath, \"parsers\", stage, name+\".yaml\")\nif fi, err := os.Lstat(dst); err == nil {\n\t_ = os.Remove(dst) // clear stale file/symlink before install\n}\n_ = fi","typeGuard":null,"tryCatchPattern":"if err := item.InstallParser(name); err != nil {\n\t// on Windows, check symlink privilege / Developer Mode first\n\treturn fmt.Errorf(\"symlink install failed for %s: %w\", name, err)\n}","preventionTips":["On Windows, enable Developer Mode or run as a user with symlink privilege.","Clean the runtime tree before each test run to avoid stale symlinks.","Verify parent directories exist before symlink-dependent steps."],"tags":["hubtest","symlink","filesystem","windows"],"backgroundTag":"file-write-failed","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"}