withastro/astro · error · Error
File path must be relative to the site root. Got: ${filePath
Error message
File path must be relative to the site root. Got: ${filePath} What it means
Thrown as a plain Error (no AstroError code) from the scoped store's set() method when the supplied filePath begins with '/'. The store expects paths relative to the site root (no leading slash); absolute paths would break module resolution and the generated import map.
Source
Thrown at packages/astro/src/content/mutable-data-store.ts:371
forEach(data, (_, val) => {
if (typeof val === 'string' && val.startsWith(IMAGE_IMPORT_PREFIX)) {
const src = val.replace(IMAGE_IMPORT_PREFIX, '');
foundAssets.add(src);
}
});
const entry: DataEntry = {
id,
data,
};
// We do it like this so we don't waste space stringifying
// the fields if they are not set
if (body) {
entry.body = body;
}
if (filePath) {
if (filePath.startsWith('/')) {
throw new Error(`File path must be relative to the site root. Got: ${filePath}`);
}
entry.filePath = filePath;
}
if (foundAssets.size) {
entry.assetImports = Array.from(foundAssets);
this.addAssetImports(entry.assetImports, filePath);
}
if (digest) {
entry.digest = digest;
}
if (rendered) {
entry.rendered = rendered;
}
if (deferredRender) {
entry.deferredRender = deferredRender;
if (filePath) {View on GitHub (pinned to d081033d5f)
Solutions
- Pass a relative path (no leading slash) — use posixRelative(root, absolutePath) to convert.
- If you have an absolute path, strip the project root prefix before passing it.
- Replicate the pattern used by the built-in file/glob loaders (they call posixRelative).
Example fix
// before
const filePath = '/src/content/posts/a.md';
context.store.set({ id, data, filePath });
// after
import { posixRelative } from 'astro/content/utils';
const filePath = posixRelative(config.root, absolutePath);
context.store.set({ id, data, filePath }); Defensive patterns
Strategy: validation
Validate before calling
import { posix } from 'node:path';
function toRelativeFilePath(p: string) {
if (p.startsWith('/')) throw new Error(`filePath must be relative: ${p}`);
return posix.normalize(p);
} Type guard
const isRelativeFilePath = (p: string) => !p.startsWith('/'); Prevention
- Convert absolute paths with posixRelative(root, abs) before passing to store.set.
- Never prefix filePath with '/'; mirrors the built-in loaders' convention.
- Add a lint rule or wrapper that rejects leading-slash filePath.
When it happens
Trigger: A loader calls context.store.set({ id, data, filePath: '/src/content/x.md' }) — passing an absolute or leading-slash path instead of a relative one.
Common situations: Using path.resolve() or fileURLToPath() without converting to a project-relative form; copying an OS-absolute path into filePath; loader code that prefixes '/' to normalize.
Related errors
- ID must be a non-empty string
- ContentLoaderReturnsInvalidId
- ContentLoaderInvalidDataError
- Glob patterns cannot start with `../`. Set the `base` option
- Glob patterns cannot start with `/`. Set the `base` option t
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/94beaa003cdd7211.
Report an issue: GitHub.