twpayne/chezmoi · error
%s: path not found in %s
Error message
%s: path not found in %s
What it means
After downloading an archive and walking it to find the entry matching external.ArchivePath, no entry matched, so sourceStateEntry stays nil and chezmoi raises 'path not found in <url>'. It means the configured archive path does not exist inside the downloaded archive.
Source
Thrown at internal/chezmoi/sourcestate.go:2739
sourceAttr: SourceAttr{
External: true,
},
}
sourceStateEntry = &SourceStateFile{
attr: fileAttr,
origin: external,
sourceRelPath: sourceRelPath,
targetStateEntry: targetStateEntry,
}
return fs.SkipAll
default:
return fmt.Errorf("%s: unsupported mode %o", name, fileInfo.Mode()&fs.ModeType)
}
}); err != nil {
return nil, err
}
if sourceStateEntry == nil {
return nil, fmt.Errorf("%s: path not found in %s", external.ArchivePath, urlStr)
}
return s.populateImplicitParentDirs(externalRelPath, external, map[RelPath][]SourceStateEntry{
externalRelPath: {sourceStateEntry},
}), nil
}
// readExternalDir returns all source state entries in an external_ dir.
func (s *SourceState) readExternalDir(
rootSourceAbsPath AbsPath,
rootSourceRelPath SourceRelPath,
rootTargetRelPath RelPath,
) (map[RelPath][]SourceStateEntry, error) {
sourceStateEntries := make(map[RelPath][]SourceStateEntry)
walkFunc := func(absPath AbsPath, fileInfo fs.FileInfo, err error) error {
switch {
case err != nil:
return errView on GitHub (pinned to f901167e46)
Solutions
- List the archive contents (tar -tzf / unzip -l <url-download>) and correct archivePath to an entry that actually exists
- Check for typos and trailing-slash/case mismatches in the archivePath value
- Pin the URL/version so the archive layout stays consistent, or update config after upstream layout changes
Example fix
// before [[external]] url = "https://github.com/x/y/archive/v2.tar.gz" archivePath = "y-2/config/old-name" # renamed upstream // after archivePath = "y-2/config/new-name"
Defensive patterns
Strategy: validation
Validate before calling
// verify archivePath exists before configuring: url=https://github.com/x/y/archive/v2.tar.gz curl -sL "$url" -o /tmp/a.tgz && tar -tzf /tmp/a.tgz | grep 'y-2/config/'
Try / catch
// wrap apply and report which external failed
if err := chezmoiApply(); err != nil {
if strings.Contains(err.Error(), "path not found in") {
log.Fatalf("external archivePath mismatch: %v — list archive contents and fix archivePath", err)
}
return err
} Prevention
- List archive contents and match archivePath exactly (case, leading path after stripComponents)
- Pin URLs/versions so upstream layout changes cannot break archivePath
- Add a CI check that downloads the archive and greps for the configured path
When it happens
Trigger: .chezmoiexternal entry with archivePath (and often exactArchivePath) referencing a file/directory that does not exist in the archive at the given URL; path spelling, case, or stripComponents mismatch.
Common situations: Upstream project renamed or moved a file inside its release tarball; typo in archivePath; archive layout changed between versions (e.g. subdir added); pinning an old URL whose layout differs from your config.
Related errors
- %d: invalid format-indent-width
- %s: unknown archive format
- %s: unsupported typeflag '%c'
- %s: unsupported file mode %o
- %s: %w
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/3f5d1e9e0c42c8fd.
Report an issue: GitHub.