gastownhall/beads · error

writing %s output: %w

Error message

writing %s output: %w

What it means

Wraps the io.Writer error accumulated by graphExportWriter when emitting `bd graph` output of a given kind (jsonl, dot, list, etc.). The underlying write failed — usually a closed/broken stdout, full disk, or closed pipe.

Source

Thrown at cmd/bd/graph_export.go:94

func (w *graphExportWriter) printf(format string, args ...interface{}) {
	if w.err != nil {
		return
	}
	_, w.err = fmt.Fprintf(w.out, format, args...)
}

func (w *graphExportWriter) println(args ...interface{}) {
	if w.err != nil {
		return
	}
	_, w.err = fmt.Fprintln(w.out, args...)
}

func (w *graphExportWriter) wrapError(kind string) error {
	if w.err == nil {
		return nil
	}
	return fmt.Errorf("writing %s output: %w", kind, w.err)
}

// dotNodeAttrs returns the DOT label, fill color, and font color for a node
func dotNodeAttrs(node *GraphNode) (label, fillColor, fontColor string) {
	icon := statusPlainIcon(node.Issue.Status)
	title := truncateTitle(node.Issue.Title, 40)
	label = fmt.Sprintf("%s %s\\nP%d | %s", icon, node.Issue.ID, node.Issue.Priority, title)

	switch node.Issue.Status {
	case types.StatusOpen:
		fillColor = "#e8f4fd"
		fontColor = "#1a1a1a"
	case types.StatusInProgress:
		fillColor = "#fff3cd"
		fontColor = "#664d03"
	case types.StatusBlocked:
		fillColor = "#f8d7da"
		fontColor = "#842029"

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check disk space and write permissions on the output target
  2. Avoid closing the pipe early (don't pipe into head/less -quit), or ignore EPIPE deliberately
  3. Redirect to a different writable location

Example fix

// before
bd graph --format dot | head -5
// after
bd graph --format dot > graph.dot && less graph.dot
Defensive patterns

Strategy: try-catch

Validate before calling

f, err := os.OpenFile(outPath, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil { return err }
if _, err := f.WriteString("probe"); err != nil { return fmt.Errorf("output not writable: %w", err) }
f.Close()

Try / catch

if err := bd.Graph(...); err != nil {
  var pe *os.PathError
  if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EPIPE) {
    return nil // consumer closed the pipe; benign
  }
  return err
}

Prevention

When it happens

Trigger: Running bd graph ... > file on a full disk; piping into `head` which closes the pipe (SIGPIPE/EPIPE); redirecting to an unwritable file.

Common situations: CI logs to a full tmpfs; `bd graph | head -5` causing broken pipe; read-only output file.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/1c9e6d56201b4cd0. Report an issue: GitHub.