charmbracelet/crush · error

could not run command: %w

Error message

could not run command: %w

What it means

After parsing succeeds, Run() constructs an interpreter via newRunner(opts.Cwd, opts.Env, ...). If interpreter construction fails (typically a bad working directory, invalid environment, or missing options), the failure is wrapped as "could not run command: %w". Unlike a parse error, the command may be valid but the runtime environment for it is not.

Source

Thrown at internal/shell/run.go:88

	}

	stdout := opts.Stdout
	if stdout == nil {
		stdout = io.Discard
	}
	stderr := opts.Stderr
	if stderr == nil {
		stderr = io.Discard
	}

	line, err := syntax.NewParser().Parse(strings.NewReader(opts.Command), "")
	if err != nil {
		return fmt.Errorf("could not parse command: %w", err)
	}

	runner, err := newRunner(opts.Cwd, opts.Env, opts.Stdin, stdout, stderr, opts.BlockFuncs)
	if err != nil {
		return fmt.Errorf("could not run command: %w", err)
	}

	return runner.Run(ctx, line)
}

// CaptureResult holds the combined output and exit code from a
// captured shell execution.
type CaptureResult struct {
	Output   string
	ExitCode int
}

// PersistFunc is a callback that persists a shell command result.
// Used by RunAndPersist to decouple execution from storage.
type PersistFunc func(command, output string, exitCode int) error

// RunAndPersist executes a shell command via PTY and optionally
// persists the result through the provided callback. This unifies

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check that opts.Cwd exists and is a directory (os.Stat) before calling Run.
  2. Verify opts.Env entries are valid KEY=VALUE strings.
  3. Ensure stdout/stderr writers are non-nil and writable (Run defaults stderr to io.Discard, stdout must be provided).
  4. Inspect the wrapped %w error for the underlying cause (e.g. 'no such file or directory').

Example fix

// before
shell.Run(ctx, shell.RunOpts{Command: "ls", Cwd: "/tmp/does-not-exist"})
// after
if _, err := os.Stat(cwd); err != nil { return fmt.Errorf("bad cwd: %w", err) }
shell.Run(ctx, shell.RunOpts{Command: "ls", Cwd: cwd})
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(opts.Cwd); err != nil {
	return fmt.Errorf("cwd unavailable: %w", err)
}
for _, e := range opts.Env {
	if !strings.Contains(e, "=") { return errors.New("bad env entry: " + e) }
}

Try / catch

if err := shell.Run(ctx, opts); err != nil {
	if strings.HasPrefix(err.Error(), "could not run command") {
		// log opts.Cwd/Env, retry after fixing setup
	}
}

Prevention

When it happens

Trigger: Calling shell.Run with RunOpts whose Cwd does not exist or is not readable, an Env in an invalid format, or nil/invalid stdin/stdout/stderr writer configuration that newRunner rejects.

Common situations: Pointing Cwd at a deleted or renamed directory; passing an env slice built incorrectly; running in a container/CI where the configured working directory was not created before invoking Run.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/c6ef249fb3e6ebd4. Report an issue: GitHub.