twpayne/chezmoi · error
%s: missing path
Error message
%s: missing path
What it means
Returned by readExternalArchive when the external entry's archivePath field is empty, i.e. an entry that requires selecting a file within an archive has no path specified. chezmoi cannot know which member of the archive to extract.
Source
Thrown at internal/chezmoi/sourcestate.go:2645
format := external.Format
if format == ArchiveFormatUnknown {
format = GuessArchiveFormat(urlPath, data)
}
return data, urlStr, format, nil
}
// readExternalArchiveFile reads a file from an external archive and returns its
// SourceStateEntries.
func (s *SourceState) readExternalArchiveFile(
ctx context.Context,
externalRelPath RelPath,
parentSourceRelPath SourceRelPath,
external *External,
options *ReadOptions,
) (map[RelPath][]SourceStateEntry, error) {
if external.ArchivePath.IsEmpty() {
return nil, fmt.Errorf("%s: missing path", externalRelPath)
}
data, urlStr, format, err := s.readExternalArchiveData(ctx, externalRelPath, external, options)
if err != nil {
return nil, err
}
var sourceStateEntry SourceStateEntry
if err := WalkArchive(data, format, func(name RelPath, fileInfo fs.FileInfo, r io.Reader, linkname string) error {
if external.StripComponents > 0 {
components := name.SplitAll()
if len(components) <= external.StripComponents {
return nil
}
name = NewRelPathFromComponents(components[external.StripComponents:]...)
}
switch {
case name.IsEmpty():View on GitHub (pinned to f901167e46)
Solutions
- Add the path field naming the file inside the archive to extract
- If the whole archive is wanted, change type to plain archive and remove the path expectation
- Validate with chezmoi apply --dry-run after editing
Example fix
// before
[.local/bin/jq]
type = "archive-file"
url = "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64"
// after
[.local/bin/jq]
type = "archive-file"
url = "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64"
path = "jq" Defensive patterns
Strategy: validation
Validate before calling
if ext.Type == "archive-file" && ext.Path == "" {
return fmt.Errorf("archive-file external %q requires a path", name)
} Type guard
func archiveFileHasPath(e External) bool { return e.Type != "archive-file" || e.Path != "" } Prevention
- Always pair type=archive-file with a path value
- List archive contents first to confirm the member name
- Dry-run apply after editing externals
When it happens
Trigger: An external entry of type archive-file (or one using archive.path/executable selection) is configured without the path key, so external.ArchivePath.IsEmpty() is true.
Common situations: Using the executable/archive-file external style but forgetting the path; renaming config keys and dropping path; copying an archive-type entry and converting it incompletely.
Related errors
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/b13ba903538eb3a0.
Report an issue: GitHub.