laravel/framework · error · ViteException
The font manifest at [{$path}] is not valid JSON.
Error message
The font manifest at [{$path}] is not valid JSON. What it means
ViteFonts::manifest() reads a font manifest JSON file (path supplied by the developer) and throws ViteException if json_decode reports an error. This protects callers from silently feeding malformed data into the CSS-resolution logic. Only triggered when the file exists and is non-JSON.
Source
Thrown at src/Illuminate/Foundation/ViteFonts.php:57
*
* @throws \Illuminate\Foundation\ViteException
*/
protected function readManifest(string $path)
{
if (isset(static::$manifests[$path])) {
return static::$manifests[$path];
}
if (! is_file($path)) {
return null;
}
$contents = file_get_contents($path);
$manifest = json_decode($contents, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new ViteException("The font manifest at [{$path}] is not valid JSON.");
}
return static::$manifests[$path] = $manifest;
}
/**
* Resolve the CSS content from the manifest.
*
* @param array<string, mixed> $manifest
* @param list<string>|null $aliases
* @param string $buildDirectory
* @return string
*
* @throws \Illuminate\Foundation\ViteException
*/
public function resolveStyleContent(array $manifest, ?array $aliases, string $buildDirectory)
{
$style = $manifest['style'] ?? null;View on GitHub (pinned to e0f6eb3518)
Solutions
- Regenerate the font manifest by rerunning the Vite build / font plugin pipeline.
- Validate the file with a JSON linter (jq . <path>) to find the syntax error.
- Confirm the configured path points to the actual generated manifest, not a staging or template file.
- Upgrade or downgrade the Vite font plugin to a version whose output this ViteFonts version understands.
Example fix
// before — manifest file contains a stray trailing comma
{ "family": "Inter", }
// after
{ "family": "Inter" } Defensive patterns
Strategy: validation
Validate before calling
$path = config('vite.fonts_manifest_path');
if ($path && is_file($path)) {
json_decode(file_get_contents($path), true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Font manifest invalid JSON: '.json_last_error_msg());
}
} Type guard
function fontManifestIsValidJson(string $path): bool {
if (! is_file($path)) return true; // missing file does not throw
json_decode(file_get_contents($path), true);
return json_last_error() === JSON_ERROR_NONE;
} Try / catch
use Illuminate\Foundation\ViteException;
try {
$fonts = app('vite.fonts')->manifest($path);
} catch (ViteException $e) {
// regenerate manifest or skip font injection
} Prevention
- Treat the font manifest as a build artifact; never hand-edit.
- Validate JSON in CI for committed manifests.
- Pin the font plugin version that produces the expected schema.
- Regenerate manifests after every Vite upgrade.
When it happens
Trigger: A font manifest path is configured and the file at that path exists but is not parseable JSON — truncated, hand-edited, BOM-prefixed, contains a PHP error mixed in, or was written by a process that errored midway.
Common situations: Vite font plugin output corrupted by a failed/aborted build. Manual edits to the manifest that broke syntax. A different file written to the expected path (e.g. an error page from a CDN). Version mismatch between the font plugin and the consuming code expecting a newer schema.
Related errors
- The font manifest [style.familyStyles] must be an object key
- The font manifest [style.variables] must be an object keyed
- Unable to locate file in Vite manifest: {$file}.
- Callback must be a callable, callback array, or a 'Class@met
- Auth guard [{$name}] is not defined.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/0bb39f19c3894db5.
Report an issue: GitHub.