{"record":{"id":"e7139a88647c3649","repo":"crowdsecurity/crowdsec","slug":"failed-to-parse-json-line-in-s-w-e7139a","errorCode":null,"errorMessage":"failed to parse JSON line in %s: %w","messagePattern":"failed to parse JSON line in (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/exprhelpers/filemap.go","lineNumber":47,"sourceCode":"type matchIndex struct {\n\t// O(1) map for \"equals\" entries (checked first).\n\tequalsMap map[string]int // exact pattern value → row index\n\n\t// Aho-Corasick automaton for \"contains\" entries (O(|haystack|) matching, checked second).\n\tacAutomaton    *aho_corasick.AhoCorasick\n\tacPatternToRow []int // AC pattern index → row index in fileMapEntry.rows\n\n\t// Pre-compiled regexps for \"regex\" entries (checked last).\n\tregexPatterns []*regexp.Regexp\n\tregexToRow    []int // regex slice index → row index in fileMapEntry.rows\n}\n\n// fileMapInit parses a single JSON line and appends it to the fileMapEntry for the given filename.\n// Three fields are mandatory: \"pattern\", \"tag\", and \"type\" (one of: \"equals\", \"contains\", \"regex\").\nfunc fileMapInit(filename string, line string) error {\n\tvar record map[string]string\n\tif err := json.Unmarshal([]byte(line), &record); err != nil {\n\t\treturn fmt.Errorf(\"failed to parse JSON line in %s: %w\", filename, err)\n\t}\n\n\tif record[\"pattern\"] == \"\" {\n\t\treturn fmt.Errorf(\"missing mandatory 'pattern' field in %s: %s\", filename, line)\n\t}\n\n\tif record[\"tag\"] == \"\" {\n\t\treturn fmt.Errorf(\"missing mandatory 'tag' field in %s: %s\", filename, line)\n\t}\n\n\tentryType := record[\"type\"]\n\tif entryType == \"\" {\n\t\treturn fmt.Errorf(\"missing mandatory 'type' field in %s: %s\", filename, line)\n\t}\n\n\tif !slices.Contains(validMapEntryTypes, entryType) {\n\t\treturn fmt.Errorf(\"unknown entry type '%s' in %s (supported: %s): %s\",\n\t\t\tentryType, filename, strings.Join(validMapEntryTypes, \", \"), line)","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/exprhelpers/filemap.go#L29-L65","documentation":"fileMapInit parses each line of a JSON-lines 'map' data file into a map[string]string. This error is thrown when the line is not valid JSON — json.Unmarshal fails with a syntax or type error that is wrapped as %w. Unlike botFileInit, unknown extra fields are allowed here (target is a generic map), so this fires purely on malformed JSON or non-string JSON values.","triggerScenarios":"A line in a map data file is not a JSON object of strings: broken syntax (unterminated string, trailing comma), a bare value like `true`, a JSON array, or nested objects/numbers for fields, e.g. {\"pattern\":\"a\",\"tag\":123}.","commonSituations":"Hand-edited lookup files with typos; exporting from CSV/spreadsheet producing invalid JSONL; a field accidentally numeric or boolean instead of a string; file truncated mid-line by a failed transfer; UTF-16/BOM encoding from Windows editors.","solutions":["Run `echo '<line>' | jq .` — the wrapped %w error names the exact syntax problem; fix that character.","Ensure every value (pattern, tag, type, extras) is a JSON string: quote numbers/booleans (\"tag\":\"123\").","Ensure the file is one JSON object per line (JSONL): no array wrappers, no inter-line commas, no BOM.","Re-encode the file as UTF-8 without BOM (`dos2unix`, editor save-as UTF-8).","Re-export the source data with a proper JSONL writer (e.g. jq -c) if a conversion step produced it."],"exampleFix":"// before\n{\"pattern\":\"foo\",\"tag\":123,}\n// after\n{\"pattern\":\"foo\",\"tag\":\"123\"}","handlingStrategy":"validation","validationCode":"// pre-validate a map file line: must be a JSON object with all-string values\nvar raw map[string]json.RawMessage\nif err := json.Unmarshal([]byte(line), &raw); err != nil {\n\treturn false\n}\nfor _, v := range raw {\n\tif !strings.HasPrefix(string(v), \"\\\"\") {\n\t\treturn false // non-string value\n\t}\n}\nreturn raw[\"pattern\"] != nil && raw[\"tag\"] != nil && raw[\"type\"] != nil","typeGuard":null,"tryCatchPattern":"if err := exprhelpers.FileInit(mapFile, \"map\"); err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse JSON line\") {\n\t\tlog.Errorf(\"malformed map entry: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Produce map files with a JSONL writer (jq -c, json.Marshal) rather than manual concatenation.","Quote all values as strings — numbers and booleans must be \"123\"/\"true\".","Normalize files to UTF-8 without BOM before loading.","CI-check every map file by unmarshalling each line into map[string]string.","pattern, tag, and type are mandatory — validate their presence alongside JSON validity."],"tags":["go","json","data-files","crowdsec"],"backgroundTag":"json-unmarshal-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"}