d2lang/d2 · error

failed to unmarshal input to graph: %s

Error message

failed to unmarshal input to graph: %s

What it means

In the served plugin's layout command, stdin is read and deserialized into a d2graph.Graph. This error means the bytes on stdin were not a valid serialized d2 graph, so layout could not start.

Source

Thrown at d2plugin/serve.go:123

	b, err := json.Marshal(flags)
	if err != nil {
		return err
	}
	_, err = ms.Stdout.Write(b)
	if err != nil {
		return err
	}
	return nil
}

func layout(ctx context.Context, p Plugin, ms *xmain.State) error {
	in, err := io.ReadAll(ms.Stdin)
	if err != nil {
		return err
	}
	var g d2graph.Graph
	if err := d2graph.DeserializeGraph(in, &g); err != nil {
		return fmt.Errorf("failed to unmarshal input to graph: %s", in)
	}
	err = p.Layout(ctx, &g)
	if err != nil {
		return err
	}
	b, err := d2graph.SerializeGraph(&g)
	if err != nil {
		return err
	}
	_, err = ms.Stdout.Write(b)
	if err != nil {
		return err
	}
	return nil
}

func postProcess(ctx context.Context, p Plugin, ms *xmain.State) error {
	in, err := io.ReadAll(ms.Stdin)

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Ensure the caller serializes the graph with d2graph.SerializeGraph and pipes it to the plugin's stdin
  2. Inspect what is actually on stdin (empty? logs mixed in?)
  3. Check that host and plugin d2 versions match

Example fix

// before
myplugin layout < notes.txt
// after
d2plugin serialize graph.json | myplugin layout
Defensive patterns

Strategy: validation

Validate before calling

var probe map[string]any
if json.Unmarshal(stdinBytes, &probe) != nil { /* not a serialized graph */ }

Type guard

func isSerializedGraph(b []byte) bool {
	var g d2graph.Graph
	return d2graph.DeserializeGraph(b, &g) == nil
}

Try / catch

if err := servePlugin(); err != nil {
	if strings.Contains(err.Error(), "failed to unmarshal input to graph") {
		log.Printf("plugin stdin was not a serialized d2 graph")
	}
}

Prevention

When it happens

Trigger: Calling the plugin binary with subcommand layout while stdin contains malformed, empty, or non-JSON data instead of d2graph.SerializeGraph output.

Common situations: Invoking the plugin manually without piping a graph, host/plugin protocol mismatch, an intermediate tool corrupting stdin.

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/4059195878518742. Report an issue: GitHub.