ory/hydra · error
ErrNoProcessPool
ErrNoProcessPool
Error message
jsonnetsecure: a process pool is required; use MakeInProcessVM to evaluate in this process without isolation
What it means
MakeSecureVM (oryx/jsonnetsecure/jsonnet.go:83, raised at :97) requires a non-nil Pool so Jsonnet snippets evaluate in an isolated worker process. It deliberately refuses to fall back to an in-process VM, because silently losing process isolation would let a malicious or memory-hungry snippet take down the caller's process. ErrNoProcessPool is a sentinel (use errors.Is to detect it).
Source
Thrown at oryx/jsonnetsecure/jsonnet.go:83
}
}
func WithJsonnetBinary(jsonnetBinaryPath string) Option {
return func(o *vmOptions) {
o.jsonnetBinaryPath = jsonnetBinaryPath
}
}
func WithProcessArgs(args ...string) Option {
return func(o *vmOptions) {
o.args = args
}
}
// ErrNoProcessPool is returned by MakeSecureVM when called without a process
// pool. It is a distinct error because the alternative — quietly returning an
// in-process VM — would strip the isolation callers of this package rely on.
var ErrNoProcessPool = errors.New("jsonnetsecure: a process pool is required; use MakeInProcessVM to evaluate in this process without isolation")
// MakeSecureVM returns a VM that evaluates snippets in a worker process taken
// from p, so that a snippet which exhausts memory, spins on the CPU, or crashes
// takes down only that worker.
//
// p is a required argument rather than an option because a VM without a pool
// offers no isolation at all. Passing a nil pool returns ErrNoProcessPool.
func MakeSecureVM(p Pool, opts ...Option) (VM, error) {
// A nil *pool inside a non-nil Pool interface is not reachable from outside
// this package (Pool has an unexported method), but check the concrete
// value anyway so a future in-package mistake cannot slip through.
concrete, _ := p.(*pool)
if p == nil || concrete == nil {
return nil, errors.WithStack(ErrNoProcessPool)
}
options := newVMOptions()
for _, o := range opts {View on GitHub (pinned to 4174065ffb)
Solutions
- Create the pool first: pool := jsonnetsecure.NewProcessPool(size), then vm, err := jsonnetsecure.MakeSecureVM(pool).
- Check for typed-nil: ensure the Pool variable actually holds a *pool from NewProcessPool, not a nil pointer stored in an interface.
- If you truly do not need isolation (trusted input, CLI tooling), switch to jsonnetsecure.MakeInProcessVM() as the error message suggests.
- Guard construction order so the pool outlives the VM and is non-nil at VM creation.
Example fix
// before var pool jsonnetsecure.Pool // nil vm, err := jsonnetsecure.MakeSecureVM(pool) // ErrNoProcessPool // after pool := jsonnetsecure.NewProcessPool(10) defer pool.Close() vm, err := jsonnetsecure.MakeSecureVM(pool)
Defensive patterns
Strategy: type-guard
Validate before calling
if pool == nil || reflect.ValueOf(pool).Kind() == reflect.Ptr && reflect.ValueOf(pool).IsNil() {
pool = jsonnetsecure.NewProcessPool(defaultSize)
}
vm, err := jsonnetsecure.MakeSecureVM(pool) Type guard
func poolReady(p jsonnetsecure.Pool) bool {
return p != nil && reflect.ValueOf(p).Kind() == reflect.Ptr && !reflect.ValueOf(p).IsNil()
} Try / catch
vm, err := jsonnetsecure.MakeSecureVM(pool)
if err != nil {
if errors.Is(err, jsonnetsecure.ErrNoProcessPool) {
// re-create pool or fall back to MakeInProcessVM for trusted input only
}
return err
} Prevention
- Initialize the pool in the same constructor that builds the VM.
- Never declare Pool-typed variables without assigning NewProcessPool output (avoids typed-nil).
- For trusted/CLI contexts, prefer MakeInProcessVM explicitly instead of passing nil.
- Add a startup assertion that the pool is non-nil before wiring dependent components.
When it happens
Trigger: Calling jsonnetsecure.MakeSecureVM(nil) or MakeSecureVM(p) where p is a nil *pool stored in a non-nil Pool interface (typed-nil), e.g. a struct field of type Pool that was never initialized with NewProcessPool.
Common situations: Constructing the VM before the pool is created or after pool initialization was skipped in tests; a typed-nil interface (var p *pool; MakeSecureVM(p) via an interface variable); refactoring that removed pool wiring from dependency injection.
Related errors
- ErrProcessPoolClosed
- newWorker: missing binary path in context
- errors.New(err)
- jsonnetsecure: " + result
- import not available %v
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/8af388890cf3f1e6.
Report an issue: GitHub.