halo-dev/halo · error · Error
ESM provider manifest must be an object.
Error message
ESM provider manifest must be an object.
What it means
Thrown by PluginServiceImpl.satisfiesRequiresVersion during install()/upgrade() when the plugin's spec.requires (a SemVer range) is not satisfied by the running Halo system version (compared on the nominal MAJOR.MINOR.PATCH only). It is an UnsatisfiedAttributeValueException (ServerWebInputException, HTTP 400) with messageDetailCode problemDetail.plugin.version.unsatisfied.requires and detail arguments [requires, systemVersion].
Source
Thrown at ui/packages/ui-plugin-bundler-kit/src/provider-manifest.ts:15
import path from "node:path";
export const ESM_PROVIDER_MANIFEST = "ui-plugin.json";
export interface EsmProviderManifest {
format: "esm";
entry: string;
style?: string;
}
export function validateEsmProviderManifest(
value: unknown
): EsmProviderManifest {
if (!isRecord(value)) {
throw new Error("ESM provider manifest must be an object.");
}
const keys = Object.keys(value).sort();
if (
!keys.includes("entry") ||
!keys.includes("format") ||
keys.some((key) => !["entry", "format", "style"].includes(key)) ||
value.format !== "esm"
) {
throw new Error(
'ESM provider manifest must contain format, entry, and optional style only with format "esm".'
);
}
if (typeof value.entry !== "string") {
throw new Error("ESM provider manifest entry is required.");
}
const manifest: EsmProviderManifest = {
format: "esm",
entry: normalizeProviderResourcePath(value.entry),View on GitHub (pinned to d2f5165f9c)
Solutions
- Upgrade Halo to a release whose MAJOR.MINOR.PATCH satisfies spec.requires.
- Lower spec.requires in plugin.yaml to a range your Halo satisfies — only if the plugin's APIs are actually compatible.
- Confirm you are reading the stable version: comparison ignores pre-release/build metadata.
Example fix
// before spec: requires: ">=2.20.0" // after — compatible with the running 2.10.x line spec: requires: ">=2.10.0"
Defensive patterns
Strategy: validation
Validate before calling
// Compare plugin.requires against the runtime system version before install.
String sys = systemVersionSupplier.get().toStableVersion().toString();
String requires = candidate.getSpec().getRequires();
if (!VersionUtils.satisfiesRequires(sys, requires)) {
// block install: requires > system version
} Try / catch
pluginService.install(path)
.onErrorResume(UnsatisfiedAttributeValueException.class, e ->
Mono.error(new BusinessException("Plugin requires a newer Halo: " + Arrays.toString(e.getDetailArguments()))) Prevention
- Document the minimum Halo version in your plugin's README and CI matrix.
- Set spec.requires to the lowest Halo version you actually test against.
- Upgrade Halo before installing plugins built for newer releases.
When it happens
Trigger: Installing or upgrading a plugin whose plugin.yaml spec.requires (e.g. ">=2.10.0") evaluates false against the current Halo version.
Common situations: Deploying a plugin built for a newer Halo onto an older instance; bumping spec.requires during plugin development past the local dev server version; operator running an outdated Halo patch line.
Related errors
- User permissions not set in PermissionUtils
- ESM provider manifest must contain format, entry, and option
- Invalid attachment
- Host runtime snapshot must expose exactly: ${SHARED_PACKAGE_
- Form field file is required
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/f906382094ad475c.
Report an issue: GitHub.