JanDeDobbeleer/oh-my-posh · error

font %v has no name table

Error message

font %v has no name table

What it means

After extension validation, `newFont` reads the font's SFNT `name` table via `readNameTable(font.Data)`. If the binary parses as a file but has no name table (`ok == false`), oh-my-posh cannot extract family/style metadata for installation and rejects it. A TTF/OTF without a name table is malformed or intentionally stripped.

Source

Thrown at src/cli/font/font.go:83

func newFont(fileName string, data []byte) (*Font, error) {
	if _, ok := fontExtensions[strings.ToLower(path.Ext(fileName))]; !ok {
		return nil, fmt.Errorf("not a font: %v", fileName)
	}

	font := &Font{
		FileName: fileName,
		Metadata: make(map[nameID]string),
		Data:     data,
	}

	table, ok, err := readNameTable(font.Data)
	if err != nil {
		return nil, err
	}

	if !ok {
		return nil, fmt.Errorf("font %v has no name table", fileName)
	}

	entries, err := parseNameTable(table)
	if err != nil {
		return nil, err
	}

	for _, entry := range entries {
		font.Metadata[entry.nameID] = entry.String()
	}

	font.Name = font.Metadata[nameFull]
	font.Family = font.Metadata[namePreferredFamily]

	if font.Family == "" {
		if v, ok := font.Metadata[nameFontFamily]; ok {
			font.Family = v
		}

View on GitHub (pinned to 0976794618)

Solutions

  1. Re-download the font from the official source — the binary is likely corrupt or stripped
  2. Validate the file locally (`fc-scan --format "%{family}" file.ttf` or FontForge) to confirm the name table exists
  3. Rebuild the font with a name table (fonttools: `fonttools ttLib` + addFeature) if it's your own subset build
  4. If you renamed a .woff2/.eot to .ttf, get the real .ttf instead

Example fix

// before
fc-scan stripped.ttf  # no name table
// after: re-download from the official release
curl -LO https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check the binary is a real SFNT font before install
b, err := os.ReadFile(path)
if err != nil { return err }
magic := string(b[0:4])
if magic != "\x00\x01\x00\x00" && magic != "OTTO" && magic != "true" {
	return fmt.Errorf("%s is not a valid TTF/OTF binary", path)
}

Type guard

func looksLikeSFNT(data []byte) bool {
	if len(data) < 4 { return false }
	m := string(data[:4])
	return m == "\x00\x01\x00\x00" || m == "OTTO" || m == "true"
}

Prevention

When it happens

Trigger: `readNameTable` returns `ok=false` (and no error) for the bytes passed to `newFont` — the file has a .ttf/.otf extension but the binary lacks the SFNT name table or is a stub/placeholder file.

Common situations: Corrupted or truncated download where bytes were silently padded; subsetted/stripped fonts produced by build pipelines that drop the name table; placeholder files in a custom zip renamed to .ttf; raw WOFF2 bytes renamed to .ttf.

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/238566ca4b85af6c. Report an issue: GitHub.