withastro/astro · error · AstroError

UnknownFilesystemError

UnknownFilesystemError

Error message

An unknown error occurred while reading or writing files to disk.

What it means

During build, the fonts Vite plugin creates the client fonts output directory (`mkdirSync` under the client output dir + assets dir) before copying fetched font files (vite-plugin-fonts.ts:371). Any failure creating that directory — EACCES/EEXIST-on-a-file/EROFS — is wrapped as `UnknownFilesystemError` with the Node error as `cause`.

Solutions

  1. Clean the output directory and rebuild: `rm -rf dist` (or your configured `outDir`).
  2. Check write permissions and free disk space for the user running the build on the output directory.
  3. Ensure the path where the fonts directory is created is a directory, not a leftover file with the same name.

Example fix

# before — failing build on stale/locked output
astro build

# after — clean then rebuild
rm -rf dist && astro build
Defensive patterns

Strategy: validation

Validate before calling

import { access, constants } from 'node:fs/promises';
// prebuild check: output dir writable and not blocked by a file
await access('./dist', constants.W_OK).catch(() => {
  throw new Error('dist is not writable by the build user');
});
const stats = await stat('./dist/client/_astro').catch(() => null);
if (stats && !stats.isDirectory()) throw new Error('_astro exists but is not a directory');

Prevention

When it happens

Trigger: Build output directory not writable (permissions, read-only filesystem), disk full, or a regular file already existing exactly where the fonts directory must be created (stale corrupted build output).

Common situations: CI containers running as non-root against mounted volumes; Docker read-only layers; builds after an interrupted run left odd artifacts in `dist`.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/0089c6ae6cde98e9. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/assets/fonts/vite-plugin-fonts.ts:371

			},
		},
		async buildEnd() {
			// Run once during the build, no matter how many environments there are
			if (built) {
				return;
			}
			if (sync || !settings.config.fonts?.length || this.environment.config.command === 'serve') {
				cleanup();
				return;
			}

			try {
				const dir = getClientOutputDirectory(settings);
				const fontsDir = new URL(`.${assetsDir}`, dir);
				try {
					mkdirSync(fontsDir, { recursive: true });
				} catch (cause) {
					throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause });
				}
				if (fontFileById) {
					logger.info(
						'assets',
						`Copying fonts (${fontFileById.size} file${fontFileById.size === 1 ? '' : 's'})...`,
					);
					await Promise.all(
						Array.from(fontFileById.entries()).map(async ([id, associatedData]) => {
							const data = await fontFetcher!.fetch({ id, ...associatedData });
							try {
								writeFileSync(new URL(id, fontsDir), data);
							} catch (cause) {
								throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause });
							}
						}),
					);
				}
			} finally {

View on GitHub (pinned to 52e6c34790)