{"record":{"id":"238566ca4b85af6c","repo":"JanDeDobbeleer/oh-my-posh","slug":"font-v-has-no-name-table","errorCode":null,"errorMessage":"font %v has no name table","messagePattern":"font (.+?) has no name table","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/font/font.go","lineNumber":83,"sourceCode":"\nfunc newFont(fileName string, data []byte) (*Font, error) {\n\tif _, ok := fontExtensions[strings.ToLower(path.Ext(fileName))]; !ok {\n\t\treturn nil, fmt.Errorf(\"not a font: %v\", fileName)\n\t}\n\n\tfont := &Font{\n\t\tFileName: fileName,\n\t\tMetadata: make(map[nameID]string),\n\t\tData:     data,\n\t}\n\n\ttable, ok, err := readNameTable(font.Data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"font %v has no name table\", fileName)\n\t}\n\n\tentries, err := parseNameTable(table)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, entry := range entries {\n\t\tfont.Metadata[entry.nameID] = entry.String()\n\t}\n\n\tfont.Name = font.Metadata[nameFull]\n\tfont.Family = font.Metadata[namePreferredFamily]\n\n\tif font.Family == \"\" {\n\t\tif v, ok := font.Metadata[nameFontFamily]; ok {\n\t\t\tfont.Family = v\n\t\t}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/font/font.go#L65-L101","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Re-download the font from the official source — the binary is likely corrupt or stripped","Validate the file locally (`fc-scan --format \"%{family}\" file.ttf` or FontForge) to confirm the name table exists","Rebuild the font with a name table (fonttools: `fonttools ttLib` + addFeature) if it's your own subset build","If you renamed a .woff2/.eot to .ttf, get the real .ttf instead"],"exampleFix":"// before\nfc-scan stripped.ttf  # no name table\n// after: re-download from the official release\ncurl -LO https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip","handlingStrategy":"validation","validationCode":"// sanity-check the binary is a real SFNT font before install\nb, err := os.ReadFile(path)\nif err != nil { return err }\nmagic := string(b[0:4])\nif magic != \"\\x00\\x01\\x00\\x00\" && magic != \"OTTO\" && magic != \"true\" {\n\treturn fmt.Errorf(\"%s is not a valid TTF/OTF binary\", path)\n}","typeGuard":"func looksLikeSFNT(data []byte) bool {\n\tif len(data) < 4 { return false }\n\tm := string(data[:4])\n\treturn m == \"\\x00\\x01\\x00\\x00\" || m == \"OTTO\" || m == \"true\"\n}","tryCatchPattern":null,"preventionTips":["Re-download fonts from official sources instead of reusing suspect copies","Verify with fc-scan or FontForge that the name table exists","Avoid renaming WOFF2/EOT files to .ttf"],"tags":["fonts","corruption","parsing"],"backgroundTag":"font-missing-name-table","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}