halo-dev/halo · error · Error

Invalid target Halo version: ${targetHaloVersion}.

Error message

Invalid target Halo version: ${targetHaloVersion}.

What it means

When the plugin path is a directory, getManifestPath iterates the DevelopmentPluginClasspath classes directories; if none contains plugin.yaml (DEFAULT_PROPERTIES_FILE_NAME) it throws this PluginRuntimeException. Surfaces during install/upgrade/reload of an unpacked plugin.

Source

Thrown at ui/packages/ui-plugin-bundler-kit/src/runtime-snapshot.ts:85

  }

  const packages = Object.fromEntries(
    SHARED_PACKAGE_ROOTS.map((root) => [
      root,
      validateSnapshotEntry(root, snapshotPackages[root]),
    ])
  ) as Record<SharedPackageRoot, HostRuntimeSnapshotEntry>;

  return deepFreeze({ haloVersion: value.haloVersion, packages });
}

export function selectHaloHostRuntimeSnapshot(
  targetHaloVersion: string,
  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."
    );
  }

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Place plugin.yaml under the classes directory inside the plugin directory (e.g. <pluginDir>/classes/plugin.yaml).
  2. Re-run the dev build/copy step that stages plugin.yaml into classes.
  3. Package the plugin as a jar instead and install the jar.
Defensive patterns

Strategy: validation

Validate before calling

// For directory installs, ensure plugin.yaml is under a classes dir.
Path dir = pluginPath;
boolean found = new DevelopmentPluginClasspath().getClassesDirectories().stream()
    .anyMatch(loc -> Files.exists(dir.resolve(loc).resolve("plugin.yaml")));
if (!found) {
    throw new IllegalStateException("No plugin.yaml under any classes directory");
}

Try / catch

pluginService.install(path)
    .onErrorResume(PluginRuntimeException.class,
        e -> Mono.error(new BusinessException("Directory missing plugin.yaml: " + e.getMessage())))

Prevention

When it happens

Trigger: Installing a plugin from a directory whose classes directories (e.g. classes/) do not contain a plugin.yaml file.

Common situations: Development mode where plugin.yaml was not copied to the classes output; wrong directory layout; building a directory distribution that omits the descriptor.

Related errors


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