withastro/astro · error · AstroError

UnknownFilesystemError

UnknownFilesystemError

Error message

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

What it means

Thrown by MutableDataStore.writeAssetImports when writing the empty-asset-imports placeholder file ('export default new Map();') fails. The underlying fs error is attached as cause. This path runs when the store has zero asset imports and tries to persist the empty default export.

Source

Thrown at packages/astro/src/content/mutable-data-store.ts:134

						const id = imageSrcToImportId(assetImport, typedEntry.filePath);
						if (id) {
							this.#assetImports.add(id);
						}
					}
				}
			}
		}
	}

	async writeAssetImports(filePath: PathLike) {
		this.#assetsFile = filePath;
		this.#rebuildAssetImports();

		if (this.#assetImports.size === 0) {
			try {
				await this.#writeFileAtomic(filePath, 'export default new Map();');
			} catch (err) {
				throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause: err });
			}
		}

		if (!this.#assetsDirty && existsSync(filePath)) {
			return;
		}
		// Import the assets, with a symbol name that is unique to the import id. The import
		// for each asset is an object with path, format and dimensions.
		// We then export them all, mapped by the import id, so we can find them again in the build.
		const imports: Array<string> = [];
		const exports: Array<string> = [];
		// Sort asset imports to ensure deterministic output across builds
		const sortedAssetImports = [...this.#assetImports].sort();
		sortedAssetImports.forEach((id, index) => {
			const symbol = `__ASTRO_IMAGE_IMPORT_${index}`;
			imports.push(`import ${symbol} from ${JSON.stringify(id)};`);
			exports.push(`[${JSON.stringify(id)}, ${symbol}]`);
		});

View on GitHub (pinned to d081033d5f)

Solutions

  1. Check the cause field on the thrown error for the real OS error code (EACCES, ENOSPC, ENOENT).
  2. Ensure the .astro/ directory exists and is writable: rm -rf .astro and re-run.
  3. Run the build with adequate filesystem permissions and free disk space.
  4. If in CI, verify the working directory is writable and not on a read-only mount.
Defensive patterns

Strategy: try-catch

Validate before calling

import { existsSync, accessSync, constants } from 'node:fs';
import { dirname } from 'node:path';
function ensureWritableDir(p: string) {
  const dir = dirname(p);
  if (!existsSync(dir)) throw new Error(`missing dir ${dir}`);
  accessSync(dir, constants.W_OK);
}

Try / catch

try {
  await store.writeAssetImports(assetsPath);
} catch (e) {
  const cause = e instanceof AstroError ? e.cause : e;
  if (cause && /EACCES|ENOENT|ENOSPC/.test((cause as Error).message)) {
    // permissions/space/path issue - surface actionable hint
  }
  throw e;
}

Prevention

When it happens

Trigger: The atomic write helper (#writeFileAtomic) fails on the assets file path: permission denied, EACCES, disk full, the target directory was deleted, or the path is read-only.

Common situations: Build output directory (.astro/) is read-only or missing; running the build as a user without write permission to the project; CI environments where .astro was made immutable; disk-full or inode exhaustion; antivirus/SELinux blocking writes.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/9067ea2d9c9917f5. Report an issue: GitHub.