twpayne/chezmoi · error

%s: cannot add chezmoi file to chezmoi (%s is protected)

Error message

%s: cannot add chezmoi file to chezmoi (%s is protected)

What it means

chezmoi protects a set of directories (options.ProtectedAbsPaths, e.g. the source directory itself and other internal state dirs). If a path being added lies under any protected directory, the add is rejected to prevent chezmoi from managing files inside its own state.

Source

Thrown at internal/chezmoi/sourcestate.go:433

		n++
	}
	destAbsPaths = destAbsPaths[:n]

	// Check for protected paths.
	for _, destAbsPath := range destAbsPaths {
		if destAbsPath == options.ConfigFileAbsPath {
			format := "%s: cannot add chezmoi's config file to chezmoi, use a config file template instead"
			return fmt.Errorf(format, destAbsPath)
		}
	}
	for _, destAbsPath := range destAbsPaths {
		for _, protectedAbsPath := range options.ProtectedAbsPaths {
			if protectedAbsPath.IsEmpty() {
				continue
			}
			if destAbsPath.HasDirPrefix(protectedAbsPath) {
				format := "%s: cannot add chezmoi file to chezmoi (%s is protected)"
				return fmt.Errorf(format, destAbsPath, protectedAbsPath)
			}
		}
	}

	type sourceUpdate struct {
		destAbsPath    AbsPath
		entryState     *EntryState
		sourceRelPaths []SourceRelPath
	}

	sourceUpdates := make([]sourceUpdate, 0, len(destAbsPaths))
	newSourceStateEntries := make(map[SourceRelPath]SourceStateEntry)
	newSourceStateEntriesByTargetRelPath := make(map[RelPath]SourceStateEntry)
	nonEmptyDirs := chezmoiset.New[SourceRelPath]()
	externalDirRelPaths := chezmoiset.New[RelPath]()
	dirRenames := make(map[AbsPath]AbsPath)
DEST_ABS_PATH:
	for _, destAbsPath := range destAbsPaths {

View on GitHub (pinned to f901167e46)

Solutions

  1. Remove the protected path from the add list; use 'chezmoi add' on specific files instead of whole directories.
  2. Use 'chezmoi ignore' or .chezmoiignore patterns to keep protected paths out of bulk adds.
  3. If you intended to edit source files, edit them directly in the source directory rather than adding them.

Example fix

// before (fails)
$ chezmoi add -r ~/.config
// after
$ chezmoi add ~/.config/git/config ~/.config/starship.toml
Defensive patterns

Strategy: validation

Validate before calling

src=$(chezmoi source-path)
case "$1" in
  "$src"|"$src"/*) echo "path is inside the protected source dir" >&2; exit 1;;
esac

Prevention

When it happens

Trigger: 'chezmoi add' (or programmatic add via SourceState update) on a destAbsPath with HasDirPrefix(protectedAbsPath) true for any non-empty protected path, e.g. adding files under ~/.local/share/chezmoi.

Common situations: Users add their entire home or .config tree with wildcards/recurse and accidentally include the source directory or other protected state; scripts using 'chezmoi add ~/.local/share/chezmoi'.

Related errors


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