d2lang/d2 · error
error reading from stdin: %w
Error message
error reading from stdin: %w
What it means
readInput reads the sketch/pad input; when the path is "-" it reads from stdin via io.ReadAll(os.Stdin). If the stdin read fails, the error is wrapped as "error reading from stdin".
Source
Thrown at d2cli/play.go:56
if err != nil {
return err
}
encoded, err := urlenc.Encode(fileRaw)
if err != nil {
return err
}
url := fmt.Sprintf("https://play.d2lang.com/?script=%s&sketch=%d&theme=%d&", encoded, sketchNumber, theme)
openBrowser(ctx, ms, url)
return nil
}
func readInput(filepath string) (string, error) {
if filepath == "-" {
data, err := io.ReadAll(os.Stdin)
if err != nil {
return "", fmt.Errorf("error reading from stdin: %w", err)
}
return string(data), nil
}
data, err := os.ReadFile(filepath)
if err != nil {
return "", xmain.UsageErrorf("%s", err.Error())
}
return string(data), nil
}
func openBrowser(ctx context.Context, ms *xmain.State, url string) {
ms.Log.Info.Printf("opening playground: %s", url)
err := xbrowser.Open(ctx, ms.Env, url)
if err != nil {
ms.Log.Warn.Printf("failed to open browser to %v: %v", url, err)
}View on GitHub (pinned to 0d69dca6f5)
Solutions
- Pipe content into the command: `cat sketch.d2 | d2 play -`
- Or pass a real file path instead of "-"
- Check that the upstream command in the pipeline succeeds
Example fix
// before d2 play - # no stdin provided // after cat sketch.d2 | d2 play -
Defensive patterns
Strategy: try-catch
Validate before calling
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) != 0 {
// stdin is a terminal, not a pipe — provide a file or pipe input
} Try / catch
input, err := readInput(path)
if err != nil {
return fmt.Errorf("pipe input: cat sketch.d2 | d2 play - (%v)", err)
} Prevention
- Always pipe data when using "-" as input path
- Prefer a real file path in CI
- Ensure upstream pipeline commands succeed
When it happens
Trigger: Running the play command with "-" as the input path (e.g. `d2 play -`) while stdin is closed, not piped, or the pipe writer errored/closed mid-stream.
Common situations: Running `d2 play -` in an interactive terminal without piping input,CI jobs where stdin is /dev/null or closed, or upstream command in a pipe failing and closing the pipe early.
Related errors
- cannot read a directory
- %s is not a supported format. Supported formats are: %s
- failed to fully compile (partial render written) %s: %w
- failed to compile %s: %w
- render target "%s" not found
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/3f87ff3f21532db4.
Report an issue: GitHub.