twpayne/chezmoi · error

%s: unknown external type: %s

Error message

%s: unknown external type: %s

What it means

This error is reported by chezmoi's source state processing when an entry in the .chezmoiexternal data (external diff or file specification) declares an 'type' field whose value is not one of the supported external types ('archive', 'file', or 'git-repo'). The format string '%s: unknown external type: %s' prefixes the error with the external entry's key/path and includes the unsupported type value, making it clear which external definition is invalid. It typically occurs when the .chezmoiexternal.toml/yaml/json file contains a typo in the type field (e.g. 'archivee' or 'git_repo' instead of 'git-repo'), or when an external spec omits a recognized type while providing a non-empty string that chezmoi cannot interpret. To fix it, edit the external entry to use one of the documented types: 'archive' for downloaded and extracted archives, 'file' for a single downloaded file, or 'git-repo' for a cloned Git repository.

Source

Thrown at internal/chezmoi/sourcestate.go:2427

	ctx context.Context,
	externalRelPath RelPath,
	parentSourceRelPath SourceRelPath,
	external *External,
	options *ReadOptions,
) (map[RelPath][]SourceStateEntry, error) {
	switch external.Type {
	case ExternalTypeArchive:
		return s.readExternalArchive(ctx, externalRelPath, parentSourceRelPath, external, options)
	case ExternalTypeArchiveFile:
		return s.readExternalArchiveFile(ctx, externalRelPath, parentSourceRelPath, external, options)
	case ExternalTypeFile:
		return s.readExternalFile(ctx, externalRelPath, parentSourceRelPath, external, options)
	case ExternalTypeGitRepo:
		return nil, nil
	case "":
		return nil, fmt.Errorf("%s: missing external type", externalRelPath)
	default:
		return nil, fmt.Errorf("%s: unknown external type: %s", externalRelPath, external.Type)
	}
}

// readExternalArchive reads an external archive and returns its
// SourceStateEntries.
func (s *SourceState) readExternalArchive(
	ctx context.Context,
	externalRelPath RelPath,
	parentSourceRelPath SourceRelPath,
	external *External,
	options *ReadOptions,
) (map[RelPath][]SourceStateEntry, error) {
	data, urlStr, format, err := s.readExternalArchiveData(ctx, externalRelPath, external, options)
	if err != nil {
		return nil, err
	}

	dirAttr := DirAttr{

View on GitHub (pinned to f901167e46)

Solutions

  1. Replace the type value with one of the valid values: archive, file, git-repo (or archive-file/executable combos per docs)
  2. Check chezmoi's external documentation for the exact spelling and allowed combinations
  3. Run chezmoi apply --dry-run to re-validate after fixing

Example fix

// before
[.tools]
    type = "zip"
    url = "https://example.com/tool.zip"
// after
[.tools]
    type = "archive"
    url = "https://example.com/tool.zip"
Defensive patterns

Strategy: validation

Validate before calling

var validTypes = map[string]bool{"archive":true,"file":true,"git-repo":true,"archive-file":true,"executable":true}
if !validTypes[ext.Type] { return fmt.Errorf("external %q has unknown type %q", name, ext.Type) }

Type guard

func knownExternalType(t string) bool {
    switch t { case "archive","file","git-repo","archive-file","executable": return true }
    return false
}

Prevention

When it happens

Trigger: .chezmoiexternal entry contains type set to a string other than archive, file, git-repo, archive-file, or executable — e.g. 'tar', 'zip', 'git', or a misspelling.

Common situations: Guessing type names instead of checking docs; copying config from another tool; capitalization mistakes like 'Archive'.

Related errors


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