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

  1. Read the stderr portion of the error — it contains the plugin's own failure message
  2. Rebuild/reinstall the plugin with `d2 plugin install` matching your d2 version
  3. Run the plugin binary manually with its flags subcommand to reproduce
  4. 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

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


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