withastro/astro · warning
Missing pages directory: ${pagesDirRootRelative}
Error message
Missing pages directory: ${pagesDirRootRelative} What it means
When building the route manifest, Astro resolves the pages directory (src/pages by default). If it does not exist on disk and no integration injected routes, Astro logs this warning and returns an empty route list — you get a page-less build/dev session instead of a hard failure.
Source
Thrown at packages/astro/src/core/routing/create-manifest.ts:134
cwd?: string;
/** fs module, for testing */
fsMod?: typeof nodeFs;
}
function createFileBasedRoutes(
{ settings, cwd, fsMod }: CreateRouteManifestParams,
logger: AstroLogger,
): RouteData[] {
const { config } = settings;
const pages = resolvePages(config);
const localFs = fsMod ?? nodeFs;
const rootPath = fileURLToPath(config.root);
const pagesPath = fileURLToPath(pages);
if (!localFs.existsSync(pages)) {
if (settings.injectedRoutes.length === 0) {
const pagesDirRootRelative = pages.href.slice(settings.config.root.href.length);
logger.warn(null, `Missing pages directory: ${pagesDirRootRelative}`);
}
return [];
}
const routes: RouteData[] = [];
const validPageExtensions = new Set<string>([
'.astro',
...SUPPORTED_MARKDOWN_FILE_EXTENSIONS,
...settings.pageExtensions,
]);
const invalidPotentialPages = new Set<string>(['.tsx', '.jsx', '.vue', '.svelte']);
const validEndpointExtensions = new Set<string>(['.js', '.ts']);
const prerender = getPrerenderDefault(settings.config);
function walk(
fs: typeof nodeFs,
dir: string,
parentSegments: RoutePart[][],View on GitHub (pinned to e294953aa8)
Solutions
- Create the missing directory (mkdir -p src/pages) and add at least one page
- If pages live elsewhere, correct srcDir (or the integration-provided pages config) so Astro scans the right folder
- If all routes come from integrations, verify the integration's injectRoute calls actually execute in astro:config:setup
Example fix
# before src/ components/ layouts/ # (no pages directory — warning on every command) # after mkdir -p src/pages echo '<html><body>Hello</body></html>' > src/pages/index.astro
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
import { resolve } from 'node:path';
if (!existsSync(resolve('src/pages'))) {
console.error('src/pages is missing — create it or fix srcDir');
process.exit(1);
} Prevention
- Keep at least one page in src/pages from project inception
- When moving pages, update srcDir in the same commit
- If all routes are injected, verify the integration loads before the first build
When it happens
Trigger: Running astro dev/build/sync when src/pages (or the pages dir derived from srcDir) does not exist and settings.injectedRoutes is empty.
Common situations: Fresh project scaffolded without pages; src/pages renamed or srcDir changed without moving files; projects expecting an adapter/integration to inject all routes while the integration fails to run.
Related errors
- Unsupported file type ${colors.bold(resolved)} found in page
- Unsupported file type ${colors.bold(file)} found in pages di
- UnknownFilesystemError
- UnknownFilesystemError
- Couldn't find component for route ${routeData.pathname}
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/b49d365d2ced3578.
Report an issue: GitHub.