ory/hydra · error
failed to write json output
Error message
failed to write json output
What it means
This error wraps a failure to write the evaluated jsonnet result to the process's stdout in the single-snippet (non `-0`) mode of the hidden `jsonnet` CLI command. The evaluation itself succeeded; only the final `io.WriteString(cmd.OutOrStdout(), json)` failed. It usually indicates the parent process that spawned this child has closed or stopped reading its stdout pipe.
Source
Thrown at oryx/jsonnetsecure/cmd.go:64
// so we still continue in this case.
SetVirtualMemoryLimit(virtualMemoryLimitBytes)
if null {
return scan(cmd.OutOrStdout(), cmd.InOrStdin())
}
input, err := io.ReadAll(cmd.InOrStdin())
if err != nil {
return errors.Wrap(err, "failed to read from stdin")
}
json, err := eval(input)
if err != nil {
return errors.Wrap(err, "failed to evaluate jsonnet")
}
if _, err := io.WriteString(cmd.OutOrStdout(), json); err != nil {
return errors.Wrap(err, "failed to write json output")
}
return nil
},
}
cmd.Flags().BoolVarP(&null, "null", "0", false,
`Read multiple snippets and parameters from stdin separated by null bytes.
Output will be in the same order as inputs, separated by null bytes.
Evaluation errors will also be reported to stdout, separated by null bytes.
Non-recoverable errors are written to stderr and the program will terminate with a non-zero exit code.`)
return cmd
}
func scan(w io.Writer, r io.Reader) error {
scanner := bufio.NewScanner(r)
scanner.Split(splitNull)
for scanner.Scan() {
json, err := eval(scanner.Bytes())View on GitHub (pinned to 4174065ffb)
Solutions
- Check that the parent process keeps the child's stdout pipe open until the child exits, and drains it promptly
- Verify stdout redirection targets are writable and have free space (df, ls -l on the target)
- If the parent imposes a 1s timeout, keep snippets small so evaluation finishes before the parent gives up
- Re-run the command manually with a simple snippet like `{}` to confirm the environment, not the snippet, is at fault
Example fix
// before: parent discards the cmd immediately on timeout cmd := exec.Command(path, args...) _ = cmd.Run() // after: ensure pipes are drained until the child exits var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() // keeps reading stdout so the child never gets EPIPE
Defensive patterns
Strategy: try-catch
Validate before calling
// parent side: verify stdout is a usable pipe/file before spawning
if f, ok := os.Stdout.(*os.File); ok {
if _, err := f.Stat(); err != nil {
return fmt.Errorf("stdout unusable: %w", err)
}
} Try / catch
if _, err := io.WriteString(cmd.OutOrStdout(), json); err != nil {
if errors.Is(err, syscall.EPIPE) {
// parent closed the pipe; exit quietly
return nil
}
return errors.Wrap(err, "failed to write json output")
} Prevention
- Always drain the child's stdout in the parent, even after a timeout, before killing it
- Check redirection targets for writability and disk space in deployment scripts
- Keep evaluations short so parents with 1s timeouts don't abandon the pipe mid-write
- Use cmd.Wait() and capture combined output in tests to surface pipe issues early
When it happens
Trigger: Running the jsonnet subprocess worker, evaluating a snippet successfully, then `io.WriteString` on stdout returns an error — typically EPIPE because the parent closed the read end of the pipe, or stdout was redirected to a full/unwritable file or closed descriptor.
Common situations: Parent process killed or exited while the worker was still evaluating; parent hit its 1s eval timeout and closed the pipe; stdout redirected to a disk-full filesystem or a file with wrong permissions; running the command interactively with stdout closed (e.g. `jsonnet >&-`).
Related errors
- unable to print to stdout
- newWorker: failed to create stdin pipe
- newWorker: failed to create stdout pipe
- newWorker: failed to create stderr pipe
- newWorker: failed to start process
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/7207bb9597a3911d.
Report an issue: GitHub.