crowdsecurity/crowdsec · error
jsonExtractType: expected type %s for target %s but found %s
Error message
jsonExtractType: expected type %s for target %s but found %s
What it means
jsonExtractType enforces the expected jsonparser.ValueType: JsonExtractSlice requires Array and JsonExtractObject requires Object. If the key path exists but holds a different type (string, number, null...), extraction fails with this message naming expected vs actual type.
Source
Thrown at pkg/exprhelpers/jsonextract.go:106
log.Tracef("extract path %+v", fullpath)
value, dataType, _, err := jsonparser.Get(
jsonparser.StringToBytes(jsblob),
fullpath...,
)
if err != nil {
if errors.Is(err, jsonparser.KeyPathNotFoundError) {
log.Debugf("Key %+v doesn't exist", target)
return nil, fmt.Errorf("key %s does not exist", target)
}
log.Errorf("jsonExtractType : %s : %s", target, err)
return nil, fmt.Errorf("jsonExtractType: %s : %w", target, err)
}
if dataType != t {
log.Errorf("jsonExtractType : expected type %s for target %s but found %s", t, target, dataType.String())
return nil, fmt.Errorf("jsonExtractType: expected type %s for target %s but found %s", t, target, dataType.String())
}
return value, nil
}
// func JsonExtractSlice(jsblob string, target string) []interface{} {
func JsonExtractSlice(params ...any) (any, error) {
jsblob := params[0].(string)
target := params[1].(string)
value, err := jsonExtractType(jsblob, target, jsonparser.Array)
if err != nil {
log.Errorf("JsonExtractSlice : %s", err)
return []interface{}(nil), nil
}
s := make([]interface{}, 0)
View on GitHub (pinned to 909b515798)
Solutions
- Confirm the actual type at that path in a sample payload and use the matching extractor (JsonExtractSlice vs JsonExtractObject)
- Treat null/absent-type cases explicitly before extraction (null dataType is a common mismatch)
- Add schema validation upstream so type changes are caught early
- Handle the error and return an empty slice/object instead of failing the expression
Example fix
// before: expects array but field may be object
vals, err := JsonExtractSlice(evt, "items")
// after: fall back on type error
vals, err := JsonExtractSlice(evt, "items")
if err != nil {
obj, oerr := JsonExtractObject(evt, "items")
if oerr != nil { return []interface{}{}, nil }
vals = []interface{}{obj}
} Defensive patterns
Strategy: fallback
Validate before calling
// no cheap pre-check via public API; validate shape with encoding/json
var probe any
if err := json.Unmarshal([]byte(jsblob), &probe); err == nil {
if v, ok := dig(probe, target); ok {
if _, isArr := v.([]any); !isArr {
return errors.New("target is not an array")
}
}
} Try / catch
vals, err := exprhelpers.JsonExtractSlice(jsblob, target)
if err != nil && strings.Contains(err.Error(), "but found") {
// type drift: fall back to tolerant extraction
return []interface{}{}, nil
} Prevention
- Pin extractor choice to the documented schema per source type
- Plan for upstream type changes (object vs array vs null)
- Prefer JsonExtract (tolerant) when the type may vary
- Alert on 'expected type ... but found' log lines — they signal schema drift
When it happens
Trigger: Calling JsonExtractSlice on a key that holds a string or object, or JsonExtractObject on a key holding an array/scalar/null; upstream field type changed between payload versions.
Common situations: API/schema drift where 'targets' becomes a string or 'details' becomes null; indexing a JSON field that is sometimes an array and sometimes a single object.
Related errors
- missing: %w
- failed to parse JSON line in %s: %w
- missing mandatory 'name' field in %s: %s
- failed to parse JSON line in %s: %w
- invalid type for headers: %T
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/aab26598f8d9f34f.
Report an issue: GitHub.