hasura/graphql-engine · error
writing output failed: %w
Error message
writing output failed: %w
What it means
This error is returned by writeByOutputFormat in the Hasura CLI when streaming the formatted JSON metadata output to the destination writer (usually stdout) fails during io.Copy. It wraps the underlying I/O error, so the real cause (broken pipe, closed stdout, disk full when redirected) is in the wrapped error chain. It only occurs in the rawOutputFormatJSON branch after the metadata has been successfully exported and indented.
Source
Thrown at cli/commands/metadata.go:113
return metadataCmd
}
func writeByOutputFormat(w io.Writer, b []byte, format rawOutputFormat) error {
var op errors.Op = "commands.writeByOutputFormat"
switch format {
case rawOutputFormatJSON:
out := new(bytes.Buffer)
err := json.Indent(out, b, "", " ")
if err != nil {
return errors.E(op, err)
}
_, err = io.Copy(w, out)
if err != nil {
return errors.E(op, fmt.Errorf("writing output failed: %w", err))
}
case rawOutputFormatYAML:
o, err := metadatautil.JSONToYAML(b)
if err != nil {
return errors.E(op, err)
}
_, err = io.Copy(w, bytes.NewReader(o))
if err != nil {
return errors.E(op, fmt.Errorf("writing output failed: %w", err))
}
default:
return errors.E(
op,
fmt.Errorf(
"output format '%v' is not supported. supported formats: %v, %v",
format,
rawOutputFormatJSON,View on GitHub (pinned to 724551b9ae)
Solutions
- Inspect the wrapped error with errors.Unwrap or go-errors chain to identify the actual I/O cause (EPIPE, no space left on device, file already closed)
- If piping to pagers like head/less, use a pager that reads all input or capture to a file first: `hasura metadata export > metadata.json`
- Free disk space or redirect to a writable location if the destination filesystem is full
- Avoid closing ec.Stdout before metadata commands finish when embedding the CLI programmatically
Example fix
# before hasura metadata export --output-format json | head -20 # after (EPIPE from head exiting early) hasura metadata export --output-format json > metadata.json && head -20 metadata.json
Defensive patterns
Strategy: try-catch
Try / catch
// Go: capture and inspect the wrapped io error
err := writeByOutputFormat(ec.Stdout, b, rawOutputFormatJSON)
if err != nil {
var opErr *net.OpError
if errors.As(err, &opErr) || strings.Contains(err.Error(), "broken pipe") {
// consumer exited early; not fatal for batch flows
log.Println("output consumer closed early:", err)
return nil
}
return err
} Prevention
- Redirect metadata output to files instead of piping to short-lived consumers
- Keep the execution context's writer open until commands complete
When it happens
Trigger: Running `hasura metadata export --output-format json` (or code calling writeByOutputFormat with rawOutputFormatJSON) where the destination writer fails mid-copy: piping output to a command that exits early (`hasura metadata export | head`), redirecting to a full filesystem, or stdout being closed by the calling process.
Common situations: Piping CLI output to `head`/`less` that terminates early (EPIPE), writing to a redirected file on a full disk, running in CI where stdout is captured and the runner is killed, or programmatic use of the EC writer after it was already closed.
Related errors
- output format '%v' is not supported. supported formats: %v,
- reading metadata failed: %w
- displaying metadata failed: %w
- error serving console: %w
- operation failed: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/1051d69b2bbe32f8.
Report an issue: GitHub.