ory/hydra · warning

errors.New(err)

Error message

errors.New(err)

What it means

In worker.eval (oryx/jsonnetsecure/jsonnet_pool.go:245), when the worker process writes to its stderr pipe, the scanner forwards the text on the stderr channel and eval converts it verbatim into an error via errors.New(err). This is how Jsonnet compile/runtime errors of the evaluated snippet are surfaced to the caller of EvaluateAnonymousSnippet.

Source

Thrown at oryx/jsonnetsecure/jsonnet_pool.go:245

				attribute.Int64("jsonnet.worker.runqueue_wait_us", (after.runqueueWait-before.runqueueWait).Microseconds()),
			)
		}()
	}

	select {
	case <-ctx.Done():
		return "", ctx.Err()
	case w.stdin <- processParams:
		break
	}

	select {
	case <-ctx.Done():
		return "", ctx.Err()
	case output := <-w.stdout:
		return output, nil
	case err := <-w.stderr:
		return "", errors.New(err)
	}
}

func (vm *processPoolVM) EvaluateAnonymousSnippet(filename string, snippet string) (_ string, err error) {
	tracer := trace.SpanFromContext(vm.ctx).TracerProvider().Tracer("")
	ctx, span := tracer.Start(vm.ctx, "jsonnetsecure.processPoolVM.EvaluateAnonymousSnippet", trace.WithAttributes(attribute.String("filename", filename)))
	defer otelx.End(span, &err)

	params := vm.params
	params.Filename = filename
	params.Snippet = snippet
	pp, err := json.Marshal(params)
	if err != nil {
		return "", errors.Wrap(err, "jsonnetsecure: marshal")
	}

	ctx = context.WithValue(ctx, contextValuePath, vm.path)
	ctx = context.WithValue(ctx, contextValueArgs, vm.args)

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Validate the snippet before evaluation (lint with an in-process jsonnet VM on trusted input, or parse-check).
  2. Read the returned error text — it is the raw Jsonnet error message; fix the snippet accordingly.
  3. Check EvaluateAnonymousSnippet's inputs: ext/TLA variables passed must be valid Jsonnet code (ExtCode/TLACode are evaluated, not literals — malformed code surfaces as a snippet error).
  4. If the message is 'ERROR: scan: ...', reduce output size or stderr volume of the snippet; if it is a timeout, optimize or split the evaluation.

Example fix

// before: ExtCode value treated as code, causing a jsonnet error
vm.ExtCode("payload", rawJSONString) // interpreted as Jsonnet, may fail

// after: quote it, or pass as a variable
vm.ExtCode("payload", fmt.Sprintf("%q", rawJSONString))
// or
vm.ExtVar("payload", rawJSONString)
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate snippet syntax with an in-process VM on trusted input
linter := jsonnetsecure.MakeInProcessVM()
if _, err := linter.EvaluateAnonymousSnippet(filename, snippet); err != nil {
    return fmt.Errorf("invalid jsonnet snippet: %w", err)
}

Try / catch

out, err := vm.EvaluateAnonymousSnippet(filename, snippet)
if err != nil {
    // err text is the raw Jsonnet error from the worker's stderr
    return fmt.Errorf("jsonnet evaluation failed for %s: %w", filename, err)
}
if strings.HasPrefix(out, "ERROR: ") {
    return fmt.Errorf("jsonnet output problem: %s", out)
}

Prevention

When it happens

Trigger: Evaluating a Jsonnet snippet that fails to parse, references undefined variables, has a runtime error (assertion failure, division by zero), or exceeds the 1 KiB stderr limit (yielding 'ERROR: scan: ...'); also when the worker emits anything on stderr for any reason.

Common situations: Tenant-supplied Jsonnet with syntax mistakes; snippets using unsupported imports (importer is disabled); snippets exceeding output limits (256 KiB stdout produces an 'ERROR: ' prefixed result, 1 KiB stderr is truncated); the eval is also aborted by the 1-second context timeout, which returns ctx.Err() instead.

Related errors


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