navidrome/navidrome · error

reading types rust template: %w

Error message

reading types rust template: %w

What it means

GenerateSharedTypesRust reads templates/types.rs.tmpl from the embedded templates FS before generating the nd-pdk-types crate root. This error wraps the FS ReadFile failure. It means the embedded template file is missing from the binary (or unreadable), not a Rust syntax problem.

Source

Thrown at plugins/cmd/ndpgen/internal/generator.go:963

	tmpl, err := template.New("types_stub").Funcs(pdkFuncMap()).Parse(string(tmplContent))
	if err != nil {
		return nil, fmt.Errorf("parsing template: %w", err)
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, symbols); err != nil {
		return nil, fmt.Errorf("executing template: %w", err)
	}

	return buf.Bytes(), nil
}

// GenerateSharedTypesRust generates the nd-pdk-types crate root (lib.rs).
func GenerateSharedTypesRust(structs []StructDef) ([]byte, error) {
	tmplContent, err := templatesFS.ReadFile("templates/types.rs.tmpl")
	if err != nil {
		return nil, fmt.Errorf("reading types rust template: %w", err)
	}
	sorted := sortedStructs(structs)
	known := map[string]bool{}
	for _, s := range sorted {
		known[s.Name] = true
	}
	tmpl, err := template.New("types_rs").Funcs(template.FuncMap{
		"rustDocComment":      RustDocComment,
		"rustFieldName":       func(n string) string { return ToSnakeCase(n) },
		"fieldRustType":       func(f FieldDef) string { return f.RustType(known) },
		"skipSerializingFunc": skipSerializingFunc,
		"indent":              indentSpaces,
	}).Parse(string(tmplContent))
	if err != nil {
		return nil, fmt.Errorf("parsing template: %w", err)
	}

	partialContent, err := templatesFS.ReadFile("templates/base64_bytes.rs.tmpl")

View on GitHub (pinned to 4ed7494a32)

Solutions

  1. Confirm templates/types.rs.tmpl exists in plugins/cmd/ndpgen/internal/ and is spelled exactly that way.
  2. Check the //go:embed directive covers all template files (e.g. embed templates/*) and rebuild.
  3. git status / git checkout -- templates/types.rs.tmpl to restore a deleted file.
  4. Run go build ./plugins/cmd/ndpgen/... to re-embed assets and retry generation.

Example fix

// before
//go:embed templates/*.go.tmpl
var templatesFS embed.FS

// after
//go:embed templates/*
var templatesFS embed.FS
Defensive patterns

Strategy: validation

Validate before calling

// verify embedded assets before generating
if _, err := templatesFS.ReadFile("templates/types.rs.tmpl"); err != nil {
    log.Fatalf("missing embedded template: %v", err)
}

Try / catch

out, err := GenerateSharedTypesRust(structs)
if err != nil {
    if errors.Is(err, os.ErrNotExist) || strings.Contains(err.Error(), "reading types rust template") {
        return fmt.Errorf("ndpgen build is missing template assets; rebuild with `go build ./plugins/cmd/ndpgen/...`: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: templatesFS.ReadFile("templates/types.rs.tmpl") fails with os.ErrNotExist (or a read error) when GenerateSharedTypesRust is called — typically because the file was deleted/renamed or embed patterns exclude it.

Common situations: Renaming templates/types.rs.tmpl without updating the embedded FS path; an //go:embed pattern (e.g. embed templates/*.go.tmpl) that omits .rs.tmpl files; building from a partial checkout where template assets weren't committed.

Related errors


AI-assisted analysis of navidrome/navidrome@4ed7494a32 (2026-09-01). Data as JSON: /api/errors/9aac68adef1d8dbd. Report an issue: GitHub.