{"record":{"id":"21c006bead2cf81a","repo":"ory/hydra","slug":"newworker-missing-binary-path-in-context","errorCode":null,"errorMessage":"newWorker: missing binary path in context","messagePattern":"newWorker: missing binary path in context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/jsonnetsecure/jsonnet_pool.go","lineNumber":125,"sourceCode":"\nfunc (*pool) private() {}\n\nfunc (p *pool) Close() {\n\tp.puddle.Close()\n}\n\nfunc (p *pool) Stat() *puddle.Stat {\n\treturn p.puddle.Stat()\n}\n\nfunc newWorker(ctx context.Context) (_ worker, err error) {\n\ttracer := trace.SpanFromContext(ctx).TracerProvider().Tracer(\"\")\n\tctx, span := tracer.Start(ctx, \"jsonnetsecure.newWorker\")\n\tdefer otelx.End(span, &err)\n\n\tpath, _ := ctx.Value(contextValuePath).(string)\n\tif path == \"\" {\n\t\treturn worker{}, errors.New(\"newWorker: missing binary path in context\")\n\t}\n\targs, _ := ctx.Value(contextValueArgs).([]string)\n\tcmd := exec.Command(path, append(args, \"-0\")...)\n\tcmd.Env = []string{\"GOMAXPROCS=1\"}\n\tcmd.WaitDelay = 100 * time.Millisecond\n\n\tspan.SetAttributes(semconv.ProcessCommand(cmd.Path), semconv.ProcessCommandArgs(cmd.Args...))\n\n\tstdin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn worker{}, errors.Wrap(err, \"newWorker: failed to create stdin pipe\")\n\t}\n\n\tin := make(chan []byte, 1)\n\tgo func(c <-chan []byte) {\n\t\tfor input := range c {\n\t\t\tif _, err := stdin.Write(append(input, 0)); err != nil {\n\t\t\t\tstdin.Close()","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/jsonnetsecure/jsonnet_pool.go#L107-L143","documentation":"newWorker (oryx/jsonnetsecure/jsonnet_pool.go:125) spawns the jsonnet worker subprocess using the binary path stored in the context under contextValuePath. If that context value is absent or empty, no executable can be launched and construction of a pool worker fails with this error.","triggerScenarios":"Acquiring a worker with a context that was not enriched with contextValuePath/contextValueArgs — i.e. any worker creation that did not go through processPoolVM.EvaluateAnonymousSnippet, which sets vm.path via WithJsonnetBinary (or the os.Executable default) into the context.","commonSituations":"Calling pool internals or puddle's CreateResource directly with a plain context.Background(); embedding the package and bypassing EvaluateAnonymousSnippet; a regression that drops the context values before Acquire, e.g. after WithContext replaced the context chain incorrectly (context values set on a different context than the one used for acquisition).","solutions":["Evaluate snippets through the public API (MakeSecureVM + EvaluateAnonymousSnippet) which injects the binary path into the context.","If constructing a VM manually, ensure NewProcessPoolVM receives opts with jsonnetBinaryPath set (WithJsonnetBinary(path) or the default os.Executable()).","Do not call puddle Acquire/CreateResource with an un-enriched context; only use contexts produced by EvaluateAnonymousSnippet.","Verify vm.path is non-empty before evaluation; os.Executable() failing silently in newVMOptions can yield an empty path."],"exampleFix":"// before: pool constructor called directly with bare context\nw, err := puddle.CreateResource(context.Background()) // missing binary path\n\n// after: go through the VM API which injects the path\nvm, _ := jsonnetsecure.MakeSecureVM(pool)\nout, err := vm.EvaluateAnonymousSnippet(\"config.jsonnet\", snippet)","handlingStrategy":"validation","validationCode":"if vmPath == \"\" {\n    return errors.New(\"jsonnetsecure: jsonnet binary path is empty; set WithJsonnetBinary or ensure os.Executable() works\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use the public API (MakeSecureVM + EvaluateAnonymousSnippet); never invoke pool internals with raw contexts.","Set WithJsonnetBinary(path) explicitly when os.Executable() may fail (e.g. unusual launch environments).","Do not replace/copy the context before Acquire in ways that drop the package's context values.","Smoke-test worker startup at boot by evaluating a trivial snippet like \"1+1\"."],"tags":["jsonnet","process-pool","missing-context-value","internal-invariant"],"backgroundTag":"missing-context-value","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}