{"record":{"id":"655f05c35c64ba8a","repo":"PHPOffice/PhpSpreadsheet","slug":"valid-directory-to-truetype-font-files-not-specifi","errorCode":null,"errorMessage":"Valid directory to TrueType Font files not specified","messagePattern":"Valid directory to TrueType Font files not specified","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/Font.php","lineNumber":544,"sourceCode":"     *\n     * @param float|int $sizeInCm Font size (in centimeters)\n     *\n     * @return float Size (in pixels)\n     */\n    public static function centimeterSizeToPixels(int|float $sizeInCm): float\n    {\n        return $sizeInCm * 37.795275591;\n    }\n\n    /**\n     * Returns the font path given the font.\n     *\n     * @return string Path to TrueType font file\n     */\n    public static function getTrueTypeFontFileFromFont(FontStyle $font, bool $checkPath = true): string\n    {\n        if ($checkPath && (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath))) {\n            throw new PhpSpreadsheetException('Valid directory to TrueType Font files not specified');\n        }\n\n        $name = $font->getName();\n        $fontArray = array_merge(self::FONT_FILE_NAMES, self::$extraFontArray);\n        if (!isset($fontArray[$name])) {\n            throw new PhpSpreadsheetException('Unknown font name \"' . $name . '\". Cannot map to TrueType font file');\n        }\n        $bold = $font->getBold();\n        $italic = $font->getItalic();\n        $index = 'x';\n        if ($bold) {\n            $index .= 'b';\n        }\n        if ($italic) {\n            $index .= 'i';\n        }\n        $fontFile = $fontArray[$name][$index];\n","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/Font.php#L526-L562","documentation":"Thrown by Font::getTrueTypeFontFileFromFont() when it needs to resolve a TrueType file but the static font directory is empty or does not exist. The library ships no font files, so the directory defaults to '' and exact text measurement cannot work until you supply one. Only code paths that measure text with GD (the 'exact' auto-size method) reach this check.","triggerScenarios":"Calling Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT) and triggering column auto-sizing on save without ever calling Font::setTrueTypeFontPath($dir); or calling Font::getTrueTypeFontFileFromFont($font) directly (it defaults to $checkPath = true). The check is `!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)`, so an empty string, a file path, or a deleted/renamed directory all throw.","commonSituations":"Enabling exact auto-size after copying code from documentation that assumes fonts are bundled; setting a path relative to the old CWD that breaks when the app runs from a different directory or under cron/queue workers; the fonts directory being absent in a Docker build (excluded by .dockerignore).","solutions":["Call Font::setTrueTypeFontPath('/absolute/path/to/fonts') early (bootstrap), pointing at a real directory containing the .ttf files for the fonts your sheets use.","Use an absolute path (e.g. via the project root constant) rather than a relative one so the check survives changes of current working directory.","Verify with is_dir(Font::getTrueTypeFontPath()) in a startup assertion, and ship the fonts directory in your deployment artifact.","If you do not need GD-accurate widths, keep Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_APPROX) (the default) and this code path is never entered."],"exampleFix":"// before\nFont::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT);\n$writer->save('out.xlsx'); // Valid directory to TrueType Font files not specified\n\n// after\nFont::setTrueTypeFontPath(dirname(__DIR__) . '/resources/fonts');\nFont::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT);","handlingStrategy":"validation","validationCode":"$dir = \\PhpOffice\\PhpSpreadsheet\\Shared\\Font::getTrueTypeFontPath();\nif ($dir === '' || !is_dir($dir) || !is_readable($dir)) {\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Font::setTrueTypeFontPath($appRoot . '/resources/fonts');\n}\nassert(is_dir(\\PhpOffice\\PhpSpreadsheet\\Shared\\Font::getTrueTypeFontPath()));","typeGuard":null,"tryCatchPattern":"try { $writer->save($path); }\ncatch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'TrueType Font files not specified')) {\n        \\PhpOffice\\PhpSpreadsheet\\Shared::class; // configure fonts then retry\n        \\PhpOffice\\PhpSpreadsheet\\Shared\\Font::setTrueTypeFontPath($fallbackDir);\n        $writer->save($path);\n    } else { throw $e; }\n}","preventionTips":["Set Font::setTrueTypeFontPath() once in bootstrap with an absolute path; never rely on the empty default when exact autosize is on.","Assert the fonts directory exists during smoke tests/deploy checks so a missing mount fails loudly at startup, not at export time."],"tags":["fonts","configuration","column-autosize","phpspreadsheet"],"backgroundTag":"missing-font-directory","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}