twpayne/chezmoi · error

%s: %w

Error message

%s: %w

What it means

When applying a modify-script (ModifyDirWithCmd / script that mutates a directory), chezmoi runs the command via system.RunCmd and wraps any failure as '<path>: <underlying error>'. The wrapped error comes from the command's non-zero exit or execution failure.

Source

Thrown at internal/chezmoi/targetstateentry.go:103

	Name  RelPath   `json:"name"  yaml:"name"`
	RunAt time.Time `json:"runAt" yaml:"runAt"`
}

// Apply updates actualStateEntry to match t.
func (t *TargetStateModifyDirWithCmd) Apply(
	system System,
	persistentState PersistentState,
	actualStateEntry ActualStateEntry,
) (bool, error) {
	if _, ok := actualStateEntry.(*ActualStateDir); !ok {
		if err := actualStateEntry.Remove(system); err != nil {
			return false, err
		}
	}

	runAt := time.Now().UTC()
	if err := system.RunCmd(t.cmdFunc()); err != nil {
		return false, fmt.Errorf("%s: %w", actualStateEntry.Path(), err)
	}

	modifyDirWithCmdStateKey := []byte(actualStateEntry.Path().String())
	if err := PersistentStateSet(
		persistentState, GitRepoExternalStateBucket, modifyDirWithCmdStateKey, &ModifyDirWithCmdState{
			Name:  actualStateEntry.Path(),
			RunAt: runAt,
		},
	); err != nil {
		return false, err
	}

	return true, nil
}

// EntryState returns t's entry state.
func (t *TargetStateModifyDirWithCmd) EntryState(umask fs.FileMode) (*EntryState, error) {
	return &EntryState{

View on GitHub (pinned to f901167e46)

Solutions

  1. Read the wrapped underlying error and fix the modify script itself (run it manually to reproduce)
  2. Ensure the script is executable and its interpreter exists on the target machine
  3. Make the script idempotent and tolerant of missing tooling/network (check command availability first)

Example fix

// before (modify script)
git -C $CHEZMOI_WORKING_TREE pull --rebase
// after
#!/bin/sh
command -v git >/dev/null || exit 0
git -C "$CHEZMOI_WORKING_TREE" pull --rebase || true
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: run the modify command yourself before apply
cmd := exec.Command("sh", "-c", scriptContents)
if out, err := cmd.CombinedOutput(); err != nil {
  return fmt.Errorf("modify script would fail: %v: %s", err, out)
}

Try / catch

if err := t.Apply(system, persistentState); err != nil {
  var wrapped = err // formatted as "<path>: <cause>"
  log.Printf("apply failed on %s: %v — run the modify script manually to debug", path, wrapped)
  return wrapped
}

Prevention

When it happens

Trigger: A modify_ script (runCmd on a directory-type target, e.g. git repo or managed-by-tool dir) exits non-zero or cannot be executed during `chezmoi apply`.

Common situations: Modify script depends on a tool not installed on the new machine; script fails due to network/auth when refreshing external content; script not executable or has a bug that only manifests under apply.

Related errors


AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01). Data as JSON: /api/errors/a8efc5f5f1c3d479. Report an issue: GitHub.