{"record":{"id":"473bdaee3c624bf4","repo":"gastownhall/beads","slug":"marshaling-html-graph-nodes-w","errorCode":null,"errorMessage":"marshaling HTML graph nodes: %w","messagePattern":"marshaling HTML graph nodes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/graph_export.go","lineNumber":167,"sourceCode":"\tcase types.StatusBlocked:\n\t\treturn \"●\"\n\tcase types.StatusClosed:\n\t\treturn \"✓\"\n\tdefault:\n\t\treturn \"❄\"\n\t}\n}\n\n// renderGraphHTML generates a self-contained HTML file with an interactive D3.js\n// force-directed graph visualization. The output is a complete HTML document that\n// can be opened in any browser.\nfunc renderGraphHTML(out io.Writer, layout *GraphLayout, subgraph *TemplateSubgraph) error {\n\tnodes := buildHTMLGraphData(layout, subgraph)\n\tedges := buildHTMLEdgeData(layout, subgraph)\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling HTML graph nodes: %w\", err)\n\t}\n\tedgesJSON, err := json.Marshal(edges)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling HTML graph edges: %w\", err)\n\t}\n\n\ttitle := \"Beads Dependency Graph\"\n\tif subgraph.Root != nil {\n\t\ttitle = fmt.Sprintf(\"Beads: %s (%s)\", subgraph.Root.Title, subgraph.Root.ID)\n\t}\n\n\tif _, err := fmt.Fprintf(out, htmlTemplate, html.EscapeString(title), string(nodesJSON), string(edgesJSON)); err != nil {\n\t\treturn fmt.Errorf(\"writing HTML output: %w\", err)\n\t}\n\treturn nil\n}\n\n// HTMLNode is the JSON structure for a node in the HTML visualization","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/graph_export.go#L149-L185","documentation":"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).","triggerScenarios":"Calling bd graph --format html where buildHTMLGraphData produced a node value json.Marshal rejects (custom MarshalJSON returning an error, invalid type).","commonSituations":"Custom/modified builds with new node fields of unmarshalable types (chan, func); regression after refactoring HTMLNode structure.","solutions":["Update/rebuild bd — stock builds should never hit this","If you modified HTMLNode/HTMLGraphData, remove non-JSON-serializable fields or add proper marshalling","Report a bug with the wrapped marshal error if it occurs on a release binary"],"exampleFix":"// before\ntype HTMLNode struct { Extra chan int `json:\"-\"` }\n// after\ntype HTMLNode struct { Extra string `json:\"extra,omitempty\"` }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := bd.Graph(ctx, \"html\"); err != nil {\n  if strings.Contains(err.Error(), \"marshaling HTML graph nodes\") {\n    // fallback to dot format which doesn't require JSON marshaling\n    return bd.Graph(ctx, \"dot\")\n  }\n  return err\n}","preventionTips":["Keep bd binaries up to date; this path is unreachable in stock builds","If extending HTMLNode, add unit tests that renderGraphHTML succeeds","Avoid non-serializable field types in graph view models"],"tags":["go","json","marshal","graph-export"],"backgroundTag":"json-marshal-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}