halo-dev/halo · warning · Error
No ESM host runtime snapshot is available for Halo ${targetH
Error message
No ESM host runtime snapshot is available for Halo ${targetHaloVersion}. Update @halo-dev/ui-plugin-bundler-kit or select IIFE output. What it means
ReverseProxyRouterFunctionFactory.getResourceLoader throws NotFoundException (HTTP 404) when BundleResourceUtils.getResourceLoader returns null for the requested plugin name — i.e. no resource loader/bundle is registered for that plugin. It occurs while serving a plugin asset route.
Source
Thrown at ui/packages/ui-plugin-bundler-kit/src/runtime-snapshot.ts:99
snapshots: readonly HaloHostRuntimeSnapshot[] = HALO_HOST_RUNTIME_SNAPSHOTS
) {
const target = parse(targetHaloVersion);
if (!target) {
throw new Error(`Invalid target Halo version: ${targetHaloVersion}.`);
}
const eligible = snapshots
.filter(
(snapshot) =>
lte(snapshot.haloVersion, target.version) ||
(target.prerelease.length > 0 &&
snapshot.haloVersion ===
`${target.major}.${target.minor}.${target.patch}`)
)
.sort((left, right) => compare(right.haloVersion, left.haloVersion));
const snapshot = eligible[0];
if (!snapshot) {
throw new Error(
`No ESM host runtime snapshot is available for Halo ${targetHaloVersion}. ` +
"Update @halo-dev/ui-plugin-bundler-kit or select IIFE output."
);
}
return {
snapshot,
reusedOlderSnapshot:
snapshot.haloVersion !==
`${target.major}.${target.minor}.${target.patch}`,
};
}
export async function resolveSharedPackage(
root: SharedPackageRoot,
providerRoot: string,
sourceId?: string
) {View on GitHub (pinned to d2f5165f9c)
Solutions
- Verify the plugin is installed and started; check its status phase is STARTED.
- Correct the plugin name in the request URL to match metadata.name.
- Reload/restart the plugin so its bundle resource loader is registered.
- Return a 404-friendly fallback in the UI instead of surfacing the raw error.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before linking a console asset URL, confirm a bundle loader exists.
DefaultResourceLoader loader = BundleResourceUtils.getResourceLoader(pluginManager, pluginName);
if (loader == null) {
// plugin not started; don't emit asset links yet
} Try / catch
// Asset route handler — return 404 instead of letting NotFoundException propagate raw.
router.route(GET("/plugins/{name}/assets/{*resource}"), request)
.onErrorResume(NotFoundException.class, e -> ServerResponse.notFound().build()) Prevention
- Only render plugin asset URLs when the plugin's status phase is STARTED.
- Validate the plugin name against installed plugins before building URLs.
- Handle 404s gracefully in the UI to avoid confusing users.
When it happens
Trigger: A GET to a plugin reverse-proxy asset route (e.g. /plugins/{name}/assets/...) where {name} has no loaded bundle (plugin not installed, not started, or misspelled).
Common situations: Requesting assets for a plugin that failed to load; typo in the plugin name in the URL; accessing assets before the plugin is started; plugin uninstalled while browsers still cache its asset URLs.
Related errors
- Invalid attachment
- User permissions not set in PermissionUtils
- ESM provider manifest must be an object.
- ESM provider manifest must contain format, entry, and option
- ESM provider manifest entry is required.
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/4353349c777f639f.
Report an issue: GitHub.