ory/hydra · error
jsonnetsecure: " + result
Error message
jsonnetsecure: " + result
What it means
EvaluateAnonymousSnippet evaluates a jsonnet snippet inside a sandboxed worker process. If the worker completes but its stdout result begins with "ERROR: ", the pool treats it as a failed evaluation and returns the payload verbatim as a Go error prefixed with "jsonnetsecure: ". The text after the prefix is the raw jsonnet error emitted by the worker (usually a jsonnet compile/runtime error with file/line context).
Source
Thrown at oryx/jsonnetsecure/jsonnet_pool.go:280
ctx = context.WithValue(ctx, contextValuePath, vm.path)
ctx = context.WithValue(ctx, contextValueArgs, vm.args)
worker, err := vm.pool.puddle.Acquire(ctx)
if err != nil {
return "", errors.Wrap(err, "jsonnetsecure: acquire")
}
ctx, cancel := context.WithTimeoutCause(ctx, 1*time.Second, errors.Errorf("failed to run jsonnet within 1s: filename=%s", filename))
defer cancel()
result, err := worker.Value().eval(ctx, pp)
if err != nil {
worker.Destroy()
return "", errors.Wrap(err, "jsonnetsecure: eval")
} else {
worker.Release()
}
if strings.HasPrefix(result, "ERROR: ") {
return "", errors.New("jsonnetsecure: " + result)
}
return result, nil
}
func NewProcessPoolVM(opts *vmOptions) VM {
ctx := opts.ctx
if ctx == nil {
ctx = context.Background()
}
return &processPoolVM{
path: opts.jsonnetBinaryPath,
args: opts.args,
ctx: ctx,
pool: opts.pool,
}
}
View on GitHub (pinned to 4174065ffb)
Solutions
- Read the text after the 'jsonnetsecure: ERROR: ' prefix — it contains the jsonnet file:line and message; fix the snippet accordingly.
- Run the snippet through a local `jsonnet` CLI (same version) to reproduce and iterate on the error quickly.
- If it's an import error, ensure the importer/security config of the pool VM permits the path or inline the data instead.
- Validate the snippet is passed as anonymous snippet (not cached/found differently) and check for accidental wrapping or escaping issues in the caller.
Example fix
// before
out, err := vm.EvaluateAnonymousSnippet("config.jsonnet", `std.extVar('missing')`)
// after
out, err := vm.EvaluateAnonymousSnippet("config.jsonnet", `{ greeting: "hello" }`) // no undefined extVars/imports Defensive patterns
Strategy: try-catch
Validate before calling
snippet := `std.extVar("missing")`
if strings.Contains(snippet, "std.extVar") && !extVarsProvided {
return fmt.Errorf("snippet uses std.extVar but no extVars were supplied")
} Try / catch
result, err := vm.EvaluateAnonymousSnippet("snippet.jsonnet", snippet)
if err != nil {
if strings.Contains(err.Error(), "ERROR: ") {
// jsonnet-level failure: surface the jsonnet message with context
return fmt.Errorf("invalid jsonnet snippet: %w", err)
}
return fmt.Errorf("worker/pool failure: %w", err)
} Prevention
- Lint jsonnet snippets with `jsonnet fmt --no-seq` or jsonnet-lint in CI before evaluating
- Keep snippets free of std.extVar / imports unless the pool VM is configured to allow them
- Pin the jsonnet library version and test snippets against the same version locally
- Wrap eval calls with context about which config file produced the snippet for faster triage
When it happens
Trigger: Calling EvaluateAnonymousSnippet (or NewProcessPoolVM-based eval) with a snippet that fails to parse, references undefined variables/functions, imports unavailable files, or triggers a jsonnet runtime error (e.g. assertion failure, division by zero).
Common situations: Malformed or hand-written jsonnet config files, typos in field names, missing imports since the sandbox cannot read arbitrary paths, using jsonnet stdlib features unsupported by the pinned jsonnet version.
Related errors
- import not available %v
- ErrNoProcessPool
- ErrProcessPoolClosed
- newWorker: missing binary path in context
- errors.New(err)
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/3db8d4a8db943349.
Report an issue: GitHub.