{"record":{"id":"9ff3f9e9e2ef539e","repo":"crowdsecurity/crowdsec","slug":"key-s-does-not-exist","errorCode":null,"errorMessage":"key %s does not exist","messagePattern":"key (.+?) does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/exprhelpers/jsonextract.go","lineNumber":98,"sourceCode":"\treturn JsonExtractLib(jsblob, fullpath)\n}\n\nfunc jsonExtractType(jsblob string, target string, t jsonparser.ValueType) ([]byte, error) {\n\tif !strings.HasPrefix(target, \"[\") {\n\t\ttarget = strings.ReplaceAll(target, \"[\", \".[\")\n\t}\n\tfullpath := strings.Split(target, \".\")\n\n\tlog.Tracef(\"extract path %+v\", fullpath)\n\n\tvalue, dataType, _, err := jsonparser.Get(\n\t\tjsonparser.StringToBytes(jsblob),\n\t\tfullpath...,\n\t)\n\tif err != nil {\n\t\tif errors.Is(err, jsonparser.KeyPathNotFoundError) {\n\t\t\tlog.Debugf(\"Key %+v doesn't exist\", target)\n\t\t\treturn nil, fmt.Errorf(\"key %s does not exist\", target)\n\t\t}\n\t\tlog.Errorf(\"jsonExtractType : %s : %s\", target, err)\n\t\treturn nil, fmt.Errorf(\"jsonExtractType: %s : %w\", target, err)\n\t}\n\n\tif dataType != t {\n\t\tlog.Errorf(\"jsonExtractType : expected type %s for target %s but found %s\", t, target, dataType.String())\n\t\treturn nil, fmt.Errorf(\"jsonExtractType: expected type %s for target %s but found %s\", t, target, dataType.String())\n\t}\n\n\treturn value, nil\n}\n\n// func JsonExtractSlice(jsblob string, target string) []interface{} {\nfunc JsonExtractSlice(params ...any) (any, error) {\n\tjsblob := params[0].(string)\n\ttarget := params[1].(string)\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/exprhelpers/jsonextract.go#L80-L116","documentation":"jsonExtractType (backing JsonExtractSlice/JsonExtractObject) walks a dotted path through a JSON blob with jsonparser. When the requested key path does not exist in the document, jsonparser returns KeyPathNotFoundError and this function surfaces it as 'key <path> does not exist'. Unlike JsonExtract, these typed extractors propagate the error instead of returning an empty result.","triggerScenarios":"Calling JsonExtractSlice(jsblob, target) or JsonExtractObject(jsblob, target) where target (dotted path, [i] for array indices) names a key missing from jsblob — typo, wrong nesting level, key absent in that particular event.","commonSituations":"Parsing heterogeneous log/agent payloads where the field is optional; renaming of upstream JSON fields; wrong case ('Request' vs 'request'); indexing past the end of an array.","solutions":["Verify the exact key path in the actual JSON payload, matching case and nesting","Check the key exists (JsonExtract returns \"\" for missing keys and can be used as a probe) before calling the typed extractors","Handle the error and fall back to an empty slice/object in the caller","Add an upstream schema check or log the raw blob when the key is expected but missing"],"exampleFix":"// before: assumes key always exists\nval, err := JsonExtractSlice(evt, \"attack_details.targets\")\n// after: probe with tolerant extractor or guard\nif JsonExtract(evt, \"attack_details.targets\") == \"\" {\n    return []interface{}{}, nil\n}\nval, err := JsonExtractSlice(evt, \"attack_details.targets\")","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(target, \"[\") == false && !json.Valid([]byte(jsblob)) {\n    return errors.New(\"blob is not valid JSON\")\n}\nprobe := exprhelpers.JsonExtract(jsblob, target)\nif probe == \"\" { return errors.New(\"key missing: \" + target) }","typeGuard":null,"tryCatchPattern":"val, err := exprhelpers.JsonExtractSlice(jsblob, target)\nif err != nil {\n    log.Debugf(\"key %s missing: %v\", target, err)\n    return []interface{}{}, nil // tolerate missing keys\n}","preventionTips":["Probe optional keys with JsonExtract (returns \"\" when absent) before typed extraction","Keep a schema of expected JSON paths per event source","Match key case exactly — JSON paths are case-sensitive","Log raw payloads when a previously-present key disappears"],"tags":["go","json","key-not-found"],"backgroundTag":"resource-not-found","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"}