{"record":{"id":"cd1f417ee403f0ad","repo":"d2lang/d2","slug":"failed-to-unmarshal-input-edges-graph-to-graph-s","errorCode":null,"errorMessage":"failed to unmarshal input edges graph to graph: %s","messagePattern":"failed to unmarshal input edges graph to graph: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2plugin/serve.go","lineNumber":180,"sourceCode":"\tinRaw, err := io.ReadAll(ms.Stdin)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar in routeEdgesInput\n\terr = json.Unmarshal(inRaw, &in)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar g d2graph.Graph\n\tif err := d2graph.DeserializeGraph(in.G, &g); err != nil {\n\t\treturn fmt.Errorf(\"failed to unmarshal input graph to graph: %s\", in)\n\t}\n\n\tvar gedges d2graph.Graph\n\tif err := d2graph.DeserializeGraph(in.GEdges, &gedges); err != nil {\n\t\treturn fmt.Errorf(\"failed to unmarshal input edges graph to graph: %s\", in)\n\t}\n\n\terr = p.RouteEdges(ctx, &g, gedges.Edges)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tb, err := d2graph.SerializeGraph(&g)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = ms.Stdout.Write(b)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2plugin/serve.go#L162-L198","documentation":"The plugin's RouteEdges RPC receives a serialized edges graph from the host process. d2graph.DeserializeGraph failed to decode in.GEdges into a d2graph.Graph, so the plugin cannot reconstruct the edges to route. This guards the plugin against malformed or incompatible serialized graph payloads.","triggerScenarios":"Calling a routing plugin (via serve-handler) with an input whose GEdges field is not valid serialized d2graph JSON, or was produced by a different d2 version with an incompatible schema.","commonSituations":"Host and plugin built from different terrastruct/d2 versions; GEdges accidentally left nil/empty or overwritten with wrong JSON; custom plugin callers hand-constructing the request struct with an invalid GEdges blob.","solutions":["Regenerate the GEdges payload with d2graph.SerializeGraph from the same d2 version as the plugin","Verify the plugin and host use the same terrastruct/d2 module version (go.mod alignment)","Inspect in.GEdges and confirm it is a valid serialized d2graph.Graph, not the DSL source or the main diagram","If writing a custom caller, serialize the edges graph exactly as the d2 plugin host does"],"exampleFix":"// before\nreq.GEdges = string(diagramJSON) // wrong payload\n// after\nvar gedges d2graph.Graph\ngedges.Edges = g.Edges\nb, _ := d2graph.SerializeGraph(&gedges)\nreq.GEdges = b","handlingStrategy":"validation","validationCode":"var check d2graph.Graph\nif err := d2graph.DeserializeGraph(in.GEdges, &check); err != nil {\n\treturn fmt.Errorf(\"invalid GEdges payload: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep host and plugin on the same terrastruct/d2 version","Always produce GEdges with d2graph.SerializeGraph","Never hand-construct plugin request payloads","Add a smoke test that round-trips Serialize/DeserializeGraph"],"tags":["plugin","deserialization","grpc"],"backgroundTag":"payload-deserialization-failed","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}