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

  1. Verify the plugin is installed and started; check its status phase is STARTED.
  2. Correct the plugin name in the request URL to match metadata.name.
  3. Reload/restart the plugin so its bundle resource loader is registered.
  4. 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

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


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/4353349c777f639f. Report an issue: GitHub.