{"record":{"id":"28e0757711590f44","repo":"laravel/framework","slug":"the-font-manifest-style-familystyles-must-be-an","errorCode":null,"errorMessage":"The font manifest [style.familyStyles] must be an object keyed by alias; the manifest was likely produced by an incompatible plugin version.","messagePattern":"The font manifest \\[style\\.familyStyles\\] must be an object keyed by alias; the manifest was likely produced by an incompatible plugin version\\.","errorType":"exception","errorClass":"ViteException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Foundation/ViteFonts.php","lineNumber":101,"sourceCode":"        };\n    }\n\n    /**\n     * Resolve filtered CSS content using per-alias fragments from the manifest.\n     *\n     * @param  array{inline?: string, file?: string, familyStyles?: array<string, string>, variables?: array<string, string>}  $style\n     * @param  list<string>  $aliases\n     * @return string\n     *\n     * @throws \\Illuminate\\Foundation\\ViteException\n     */\n    protected function resolveFilteredStyleContent(array $style, array $aliases)\n    {\n        $familyStyles = $style['familyStyles'] ?? [];\n        $variables = $style['variables'] ?? [];\n\n        if (! is_array($familyStyles)) {\n            throw new ViteException(\n                'The font manifest [style.familyStyles] must be an object keyed by alias; the manifest was likely produced by an incompatible plugin version.'\n            );\n        }\n\n        if (! is_array($variables)) {\n            throw new ViteException(\n                'The font manifest [style.variables] must be an object keyed by alias; the manifest was likely produced by an incompatible plugin version.'\n            );\n        }\n\n        $parts = [];\n\n        foreach ($aliases as $alias) {\n            if (isset($familyStyles[$alias])) {\n                $parts[] = $familyStyles[$alias];\n            }\n        }\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Foundation/ViteFonts.php#L83-L119","documentation":"Inside resolveFilteredStyleContent(), the code expects $style['familyStyles'] to be an associative array keyed by alias. If the key is present but not an array (e.g. a string, int, or nested object of the wrong shape), ViteException is thrown. The message explicitly blames an incompatible plugin version, because the familyStyles object schema is a contract between the font plugin and this resolver.","triggerScenarios":"The font manifest's style entries have a 'familyStyles' field that is not a JSON object. Happens when the font plugin that wrote the manifest emits familyStyles as a flat string, a list, or omits the alias-keyed object shape this version of ViteFonts expects.","commonSituations":"Upgrading Laravel/Vite integration without upgrading the font plugin, or vice versa. Mixing manifests from a different font pipeline (e.g. switched from one Vite font plugin to another). Editing the manifest by hand.","solutions":["Align versions: use the font plugin version documented for this Laravel release.","Regenerate the manifest so familyStyles is an object keyed by alias, e.g. {\"default\": \"@font-face {...}\"}.","Inspect the offending style entry with jq '.styles[] | {familyStyles}' to see the wrong shape.","If you cannot change the producer, filter the alias list passed to resolveFilteredStyleContent to aliases that match the producer's schema."],"exampleFix":"// before — producer emits a string\n{ \"style\": { \"familyStyles\": \"@font-face{...}\" } }\n\n// after — alias-keyed object\n{ \"style\": { \"familyStyles\": { \"default\": \"@font-face{...}\" } } }","handlingStrategy":"validation","validationCode":"$manifest = json_decode(file_get_contents($path), true);\nforeach ($manifest['styles'] ?? [] as $style) {\n    if (isset($style['familyStyles']) && ! is_array($style['familyStyles'])) {\n        throw new RuntimeException('familyStyles must be an object; plugin version mismatch.');\n    }\n}","typeGuard":"function familyStylesWellShaped(array $style): bool {\n    return ! isset($style['familyStyles']) || is_array($style['familyStyles']);\n}","tryCatchPattern":"use Illuminate\\Foundation\\ViteException;\n\ntry {\n    $css = $viteFonts->resolveFilteredStyleContent($style, $aliases);\n} catch (ViteException $e) {\n    if (str_contains($e->getMessage(), 'familyStyles')) { /* rebuild manifest */ }\n}","preventionTips":["Keep font plugin and Laravel Vite integration versions in lockstep.","Add a CI lint that asserts style.familyStyles is an object in the generated manifest.","Regenerate manifests whenever either side upgrades.","Never author the manifest by hand."],"tags":["vite","laravel","fonts","manifest","schema"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}