withastro/astro · error · Error
Unable to resolve [${specifier}]
Error message
Unable to resolve [${specifier}] What it means
`productionEnvironment.resolve` maps an entry specifier (for example a client script or style entry emitted during build) through `manifest.entryModules` to its bundled path, then turns that into an asset link honoring `base` and `assetsPrefix`. If the specifier is not a key in `entryModules`, it throws `Unable to resolve [<specifier>]` — the requested entry was never emitted into this build's manifest.
Source
Thrown at packages/astro/src/core/environment/production.ts:78
manifest: SSRManifest,
routeData: RouteData,
): Promise<ComponentInstance> {
const module = await getModuleForRoute(manifest, routeData);
return module.page();
}
/**
* The production / bundled environment — the default when nothing is
* registered. A stateless module constant derived from the manifest alone.
*/
export const productionEnvironment: RenderEnvironment = {
name: 'production',
runtimeMode: 'production',
defaultStreaming: () => true,
async resolve(manifest: SSRManifest, specifier: string): Promise<string> {
if (!(specifier in manifest.entryModules)) {
throw new Error(`Unable to resolve [${specifier}]`);
}
const bundlePath = manifest.entryModules[specifier];
if (bundlePath.startsWith('data:') || bundlePath.length === 0) {
return bundlePath;
} else {
return createAssetLink(bundlePath, manifest.base, manifest.assetsPrefix);
}
},
async headElements(manifest: SSRManifest, routeData: RouteData): Promise<HeadElements> {
const { assetsPrefix, base } = manifest;
const routeInfo = manifest.routes.find((route) => route.routeData.route === routeData.route);
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
const links = new Set<never>();
const scripts = new Set<SSRElement>();
const styles = createStylesheetElementSet(routeInfo?.styles ?? [], base, assetsPrefix);
for (const script of routeInfo?.scripts ?? []) {View on GitHub (pinned to 52e6c34790)
Solutions
- Rebuild and redeploy server + client output together so `entryModules` matches the assets on disk.
- Grep the built SSR manifest for the specifier to confirm whether the build emitted it at all.
- If writing an integration, only resolve specifiers that were registered during the same build; guard unknown ones.
- Check that conditional emission (route filters, `output` flags) did not skip the entry your code unconditionally resolves.
Example fix
// before — resolving an entry the build never emitted
const url = await env.resolve(manifest, 'src/scripts/quantum.js'); // throws
// after — only resolve entries present in the manifest
if ('src/scripts/quantum.js' in manifest.entryModules) {
const url = await env.resolve(manifest, 'src/scripts/quantum.js');
} Defensive patterns
Strategy: type-guard
Validate before calling
// Before resolving an asset entry, confirm the build emitted it
if (!('src/scripts/quantum.js' in manifest.entryModules)) {
return '/fallback.js';
}
const url = await env.resolve(manifest, 'src/scripts/quantum.js'); Type guard
function hasEntry(
manifest: { entryModules: Record<string, string> },
specifier: string,
): specifier is keyof typeof manifest.entryModules & string {
return specifier in manifest.entryModules;
} Try / catch
try {
const url = await env.resolve(manifest, specifier);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Unable to resolve [')) {
return fallbackAssetUrl(specifier);
}
throw err;
} Prevention
- Deploy server bundle and client assets from the same build, atomically.
- In integrations, only resolve specifiers that were registered during the current build.
- Watch conditional emission (route filters, output mode) when code resolves entries unconditionally.
When it happens
Trigger: Code or an integration calling `environment.resolve(manifest, specifier)` for an entry that build did not register (conditionally emitted scripts, filtered routes); server bundle and client assets deployed from different builds so the manifest lacks the entry; a typo'd specifier in custom integration code.
Common situations: Partial deploys where `_astro` client assets and the server manifest mismatch; custom renderers/integrations resolving hand-constructed specifiers; asset manifest pruned by post-processing.
Related errors
- Unexpectedly unable to find a component instance for route $
- Astro couldn't find the correct page to render, probably bec
- Astro couldn't find the correct page to render, probably bec
- Astro couldn't find the correct page to render, probably bec
- [astro:actions] `defineAction()` unexpectedly used on the cl
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/9e06e14415b4f495.
Report an issue: GitHub.