halo-dev/halo · warning · Error

ESM UI provider output is missing its entry asset ${entryFil

Error message

ESM UI provider output is missing its entry asset ${entryFile}.

What it means

normalizeResourcePath throws this IllegalArgumentException when the entry/style path, after backslash-to-slash conversion, has no text. Caught upstream and surfaced as ClassifiedProvider.invalid.

Source

Thrown at ui/packages/ui-plugin-bundler-kit/src/rsbuild-esm.ts:59

      );

      api.processAssets(
        { stage: "summarize" },
        async ({ assets, compilation, sources }) => {
          const entryFiles =
            compilation.entrypoints.get("main")?.getFiles() || [];
          const entryScripts = entryFiles.filter((fileName) =>
            fileName.endsWith(".js")
          );
          if (entryScripts.length !== 1) {
            throw new Error(
              "ESM UI provider output must contain exactly one entry JavaScript file."
            );
          }
          const entryFile = entryScripts[0];
          const entry = assets[entryFile];
          if (!entry) {
            throw new Error(
              `ESM UI provider output is missing its entry asset ${entryFile}.`
            );
          }
          const entryCode = entry.source().toString();
          await validator.validateSource(entryCode, entryFile);
          if (
            !/\bexport\s+default\b/.test(entryCode) &&
            !/\bexport\s*\{[^}]*\bdefault\b[^}]*\}/s.test(entryCode)
          ) {
            throw new Error(
              "ESM UI provider output must expose a default PluginModule export."
            );
          }
          const entryStyles =
            compilation.entrypoints
              .get("main")
              ?.getFiles()
              .filter((fileName) => fileName.endsWith(".css")) || [];

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Provide a non-empty relative path for entry (and style) in ui-plugin.json.
  2. Drop the optional style field entirely if no stylesheet is needed.
  3. Assert non-blank paths in the plugin build before packaging.

Example fix

// before
{
  "format": "esm",
  "entry": ""
}
// after
{
  "format": "esm",
  "entry": "index.js"
}
Defensive patterns

Strategy: validation

Validate before calling

String p = manifest.path("entry").asText();
if (!StringUtils.hasText(p.replace('\\', '/').trim())) {
    throw new IllegalStateException("ui-plugin.json entry must not be blank");
}

Prevention

When it happens

Trigger: ui-plugin.json's entry or style is an empty string or whitespace only.

Common situations: Manifest templated with an unset variable producing ""; leftover placeholder cleared to blank.

Related errors


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