golang/go · error

cannot embed file %s: invalid name %s

Error message

cannot embed file %s: invalid name %s

What it means

Inside WalkDir over an embedded DIRECTORY (line 2260 region), for each non-hidden entry (name not starting with '.' or '_') the loader checks isBadEmbedName. A bad name here is fatal (returns an error from the WalkDir callback) and is reported as 'cannot embed file <rel>: invalid name <name>'. Unlike the single-file case this also fires for entries inside an embedded directory.

Source

Thrown at src/cmd/go/internal/load/pkg.go:2275

					if err != nil {
						return err
					}
					rel := filepath.ToSlash(str.TrimFilePathPrefix(path, pkgdir))
					name := d.Name()
					if path != file && (isBadEmbedName(name) || ((name[0] == '.' || name[0] == '_') && !all)) {
						// Avoid hidden files that user may not know about.
						// See golang.org/issue/42328.
						if d.IsDir() {
							return fs.SkipDir
						}
						// Ignore hidden files.
						if name[0] == '.' || name[0] == '_' {
							return nil
						}
						// Error on bad embed names.
						// See golang.org/issue/54003.
						if isBadEmbedName(name) {
							return fmt.Errorf("cannot embed file %s: invalid name %s", rel, name)
						}
						return nil
					}
					if d.IsDir() {
						if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
							return filepath.SkipDir
						}
						return nil
					}
					if !d.Type().IsRegular() {
						return nil
					}
					count++
					if have[rel] != pid {
						have[rel] = pid
						list = append(list, rel)
					}
					return nil

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Rename every visible file in the embedded directory to use only ASCII letters, digits, dot, underscore, hyphen.
  2. Prefix badly-named files with '.' or '_' if they should be skipped rather than embedded (then they are ignored, not embedded).
  3. Narrow the embed to a sanitized subdirectory.

Example fix

// before: //go:embed assets  containing assets/Notes (final).txt
// after: rename to assets/notes_final.txt
Defensive patterns

Strategy: validation

Validate before calling

// Scan an embedded directory and fail fast on any VISIBLE file whose
// name isBadEmbedName would reject (matches the per-file rule of 884).
package embedcheck

func ScanEmbedDir(dir string) error {
	entries, err := os.ReadDir(dir)
	if err != nil {
		return err
	}
	for _, e := range entries {
		name := e.Name()
		if name[0] == '.' || name[0] == '_' {
			continue // hidden, skipped by go:embed
		}
		if err := ValidEmbedFileName(name); err != nil {
			return errors.New(dir + "/" + name + ": " + err.Error())
		}
	}
	return nil
}

Prevention

When it happens

Trigger: //go:embed of a directory that contains a non-hidden file with a space, parenthesis, colon, or non-ASCII character in its name. Hidden files ('.'/'_' prefix) are silently skipped, but a visible badly-named file aborts.

Common situations: Dropping a designer's asset folder full of `Icon (2).png`-style names into an embedded dir; CI checking out files with characters that isBadEmbedName rejects; cross-platform filename issues.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/2989347c6926e67d. Report an issue: GitHub.