gastownhall/beads · error

marshaling HTML graph nodes: %w

Error message

marshaling HTML graph nodes: %w

What it means

renderGraphHTML fails when json.Marshal cannot serialize the HTMLGraphData nodes. This should be practically unreachable for plain structs of strings/slices, so it usually indicates an unexpected value (e.g. an unsupported type introduced by a custom marshaller).

Source

Thrown at cmd/bd/graph_export.go:167

	case types.StatusBlocked:
		return "●"
	case types.StatusClosed:
		return "✓"
	default:
		return "❄"
	}
}

// renderGraphHTML generates a self-contained HTML file with an interactive D3.js
// force-directed graph visualization. The output is a complete HTML document that
// can be opened in any browser.
func renderGraphHTML(out io.Writer, layout *GraphLayout, subgraph *TemplateSubgraph) error {
	nodes := buildHTMLGraphData(layout, subgraph)
	edges := buildHTMLEdgeData(layout, subgraph)

	nodesJSON, err := json.Marshal(nodes)
	if err != nil {
		return fmt.Errorf("marshaling HTML graph nodes: %w", err)
	}
	edgesJSON, err := json.Marshal(edges)
	if err != nil {
		return fmt.Errorf("marshaling HTML graph edges: %w", err)
	}

	title := "Beads Dependency Graph"
	if subgraph.Root != nil {
		title = fmt.Sprintf("Beads: %s (%s)", subgraph.Root.Title, subgraph.Root.ID)
	}

	if _, err := fmt.Fprintf(out, htmlTemplate, html.EscapeString(title), string(nodesJSON), string(edgesJSON)); err != nil {
		return fmt.Errorf("writing HTML output: %w", err)
	}
	return nil
}

// HTMLNode is the JSON structure for a node in the HTML visualization

View on GitHub (pinned to 71377f2769)

Solutions

  1. Update/rebuild bd — stock builds should never hit this
  2. If you modified HTMLNode/HTMLGraphData, remove non-JSON-serializable fields or add proper marshalling
  3. Report a bug with the wrapped marshal error if it occurs on a release binary

Example fix

// before
type HTMLNode struct { Extra chan int `json:"-"` }
// after
type HTMLNode struct { Extra string `json:"extra,omitempty"` }
Defensive patterns

Strategy: try-catch

Try / catch

if err := bd.Graph(ctx, "html"); err != nil {
  if strings.Contains(err.Error(), "marshaling HTML graph nodes") {
    // fallback to dot format which doesn't require JSON marshaling
    return bd.Graph(ctx, "dot")
  }
  return err
}

Prevention

When it happens

Trigger: Calling bd graph --format html where buildHTMLGraphData produced a node value json.Marshal rejects (custom MarshalJSON returning an error, invalid type).

Common situations: Custom/modified builds with new node fields of unmarshalable types (chan, func); regression after refactoring HTMLNode structure.

Related errors


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