projectdiscovery/nuclei · error
could not compile json: %s
Error message
could not compile json: %s
What it means
Template compilation error from Extractor.CompileExtractors (pkg/operators/extractors/compile.go:51). The json extractor's gojq query parses successfully but fails the gojq.Compile step, which type-checks the AST (function arity, unknown built-ins, invalid option usage).
Source
Thrown at pkg/operators/extractors/compile.go:51
compiled, err := regexp.Compile(regex)
if err != nil {
return fmt.Errorf("could not compile regex: %s", regex)
}
_ = cache.Regex().Set(regex, compiled)
e.regexCompiled = append(e.regexCompiled, compiled)
}
for i, kval := range e.KVal {
e.KVal[i] = strings.ToLower(kval)
}
for _, query := range e.JSON {
query, err := gojq.Parse(query)
if err != nil {
return fmt.Errorf("could not parse json: %s", query)
}
compiled, err := gojq.Compile(query)
if err != nil {
return fmt.Errorf("could not compile json: %s", query)
}
e.jsonCompiled = append(e.jsonCompiled, compiled)
}
for _, dslExp := range e.DSL {
if cached, err := cache.DSL().GetIFPresent(dslExp); err == nil && cached != nil {
e.dslCompiled = append(e.dslCompiled, cached)
continue
}
compiled, err := govaluate.NewEvaluableExpressionWithFunctions(dslExp, dsl.HelperFunctions)
if err != nil {
return &dsl.CompilationError{DslSignature: dslExp, WrappedError: err}
}
_ = cache.DSL().Set(dslExp, compiled)
e.dslCompiled = append(e.dslCompiled, compiled)
}
if e.CaseInsensitive {View on GitHub (pinned to 265b3a3dec)
Solutions
- Simplify the query to well-supported core builtins (.x | .[0], //, | tostring, | tonumber, ltrimstr/1 etc.) and check arity
- Run the exact query through `gojq` at the version nuclei vendors to confirm it compiles
- Move complex transformation into a DSL extractor (type: dsl) where helper functions are richer
- Re-validate the template after upgrading nuclei/gojq versions
Example fix
# before (invalid arity)
json:
- '.token | ltrimstr()'
# after
json:
- '.token | ltrimstr("Bearer ")' Defensive patterns
Strategy: validation
Validate before calling
for _, q := range ex.JSON {
ast, err := gojq.Parse(q)
if err != nil { return err }
if _, err := gojq.Compile(ast); err != nil {
return fmt.Errorf("query %q compiles-parse but fails gojq.Compile: %w", q, err)
}
} Type guard
func compilableGojq(q string) bool { ast, err := gojq.Parse(q); if err != nil { return false }; _, err = gojq.Compile(ast); return err == nil } Try / catch
if err := ex.CompileExtractors(); err != nil && strings.Contains(err.Error(), "could not compile json") {
// report unsupported builtin/arity; suggest DSL extractor for heavy transforms
} Prevention
- Stick to core jq builtins and correct arity
- Pin/track the gojq version vendored by your nuclei version when writing advanced queries
- Move complex shaping to type: dsl extractors
When it happens
Trigger: Queries calling a jq builtin gojq does not implement, wrong function arity (e.g. 'ltrimstr()' with no args or 'ascii_downcase(1)'), or invalid use of operators that parse but do not compile.
Common situations: Templates tested against a full jq build using rarely supported builtins or flags; version drift where the template was written for a newer gojq than the embedded nuclei version ships.
Related errors
- could not parse json: %s
- unknown extractor type specified: %s
- regex extractor group must be >= 0, got %d
- could not compile regex: %s
- case-insensitive flag is supported only for 'kval' extractor
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/7688a19340d79fb7.
Report an issue: GitHub.