d2lang/d2 · error
%v stderr: %s
Error message
%v stderr: %s
What it means
execPlugin.Flags runs a compiled d2 plugin binary with the flags subcommand. If the binary exits non-zero and wrote to stderr, the error combines the exec.ExitError with the plugin's stderr so the plugin's own diagnostic is surfaced.
Source
Thrown at d2plugin/exec.go:58
// If any errors occur the binary will exit with a non zero status code and write
// the error to stderr.
type execPlugin struct {
path string
opts map[string]string
info *PluginInfo
}
func (p *execPlugin) Flags(ctx context.Context) (_ []PluginSpecificFlag, err error) {
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
cmd := exec.CommandContext(ctx, p.path, "flags")
defer xdefer.Errorf(&err, "failed to run %v", cmd.Args)
stdout, err := cmd.Output()
if err != nil {
ee := &exec.ExitError{}
if errors.As(err, &ee) && len(ee.Stderr) > 0 {
return nil, fmt.Errorf("%v\nstderr:\n%s", ee, ee.Stderr)
}
return nil, err
}
var flags []PluginSpecificFlag
err = json.Unmarshal(stdout, &flags)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal json: %w", err)
}
return flags, nil
}
func (p *execPlugin) HydrateOpts(opts []byte) error {
if opts != nil {
var execOpts map[string]interface{}
err := json.Unmarshal(opts, &execOpts)View on GitHub (pinned to 0d69dca6f5)
Solutions
- Read the stderr portion of the error — it contains the plugin's own failure message
- Rebuild/reinstall the plugin with `d2 plugin install` matching your d2 version
- Run the plugin binary manually with its flags subcommand to reproduce
- Verify the plugin path in d2 config points to the right binary
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure plugin binary exists and is runnable before use
if _, err := os.Stat(pluginPath); err != nil {
return fmt.Errorf("plugin binary missing: %w", err)
}
cmd := exec.Command(pluginPath, "version")
if err := cmd.Run(); err != nil {
return fmt.Errorf("plugin not executable: %w", err)
} Type guard
func hasPluginStderr(err error) bool {
return strings.Contains(err.Error(), "\nstderr:\n")
} Try / catch
flags, err := plugin.Flags()
if err != nil {
if strings.Contains(err.Error(), "stderr:") {
log.Fatalf("plugin crashed: %v", err) // stderr details included
}
return err
} Prevention
- Keep plugin binaries in sync with your d2 version
- Reinstall plugins after upgrading d2 (d2 plugin install)
- Smoke-test plugin binaries in CI before relying on them
When it happens
Trigger: Calling plugin.Flags() when the plugin binary fails during flag discovery — bad plugin version, plugin crashing on startup, or plugin rejecting a CLI argument.
Common situations: Stale or incompatible d2 plugin binary on PATH; plugin built against a different d2plugin protocol; missing runtime deps for the plugin.
Related errors
- plugin has routing feature but does not implement RoutingPlu
- failed to unmarshal json: %w
- plugin has routing feature but does not implement RoutingPlu
- failed to unmarshal input to graph: %s
- failed to unmarshal input graph to graph: %s
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/d77dc5ba3cb85dd6.
Report an issue: GitHub.