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

  1. Read the text after the 'jsonnetsecure: ERROR: ' prefix — it contains the jsonnet file:line and message; fix the snippet accordingly.
  2. Run the snippet through a local `jsonnet` CLI (same version) to reproduce and iterate on the error quickly.
  3. If it's an import error, ensure the importer/security config of the pool VM permits the path or inline the data instead.
  4. 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

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


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/3db8d4a8db943349. Report an issue: GitHub.