halo-dev/halo · error · Error
Host runtime snapshot must expose exactly: ${SHARED_PACKAGE_
Error message
Host runtime snapshot must expose exactly: ${SHARED_PACKAGE_ROOTS.join(", ")}. What it means
YamlPluginFinder.unstructuredToPlugin loads the descriptor YAML and requires exactly one YAML document; if the loader returns zero or more than one Unstructured, this PluginRuntimeException is thrown (the file name placeholder is the configured propertiesFileName).
Source
Thrown at ui/packages/ui-plugin-bundler-kit/src/runtime-snapshot.ts:64
if (
!isRecord(value) ||
typeof value.haloVersion !== "string" ||
!parseStableVersion(value.haloVersion)
) {
throw new Error("Host runtime snapshot haloVersion must be stable semver.");
}
if (!isRecord(value.packages)) {
throw new Error("Host runtime snapshot packages must be an object.");
}
const snapshotPackages = value.packages;
const packageRoots = Object.keys(value.packages).sort();
const supportedRoots = [...SHARED_PACKAGE_ROOTS].sort();
if (
packageRoots.length !== supportedRoots.length ||
packageRoots.some((root, index) => root !== supportedRoots[index])
) {
throw new Error(
`Host runtime snapshot must expose exactly: ${SHARED_PACKAGE_ROOTS.join(", ")}.`
);
}
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
) {View on GitHub (pinned to d2f5165f9c)
Solutions
- Ensure plugin.yaml contains exactly one Plugin document (apiVersion + kind: Plugin).
- Remove extra '---' separators and any second document.
- Validate that the file is non-empty and parses to a single YAML mapping.
Example fix
// before — two documents
apiVersion: v1alpha1
kind: Plugin
metadata: { name: p1 }
spec: { version: 1.0.0 }
---
apiVersion: v1alpha1
kind: Plugin
metadata: { name: p2 }
// after — single document
apiVersion: v1alpha1
kind: Plugin
metadata: { name: p1 }
spec: { version: 1.0.0 } Defensive patterns
Strategy: validation
Validate before calling
List<Unstructured> docs = new YamlUnstructuredLoader(resource).load();
if (docs.size() != 1) {
throw new IllegalStateException("plugin.yaml must contain exactly one Plugin document");
} Try / catch
pluginService.install(path)
.onErrorResume(PluginRuntimeException.class,
e -> Mono.error(new BusinessException("Malformed plugin.yaml: " + e.getMessage()))) Prevention
- Keep plugin.yaml to a single Plugin document.
- Remove stray '---' separators.
- Lint the YAML in CI.
When it happens
Trigger: plugin.yaml is empty, contains multiple --- separated documents, or holds a non-Plugin document, so the loaded Unstructured list size is not 1.
Common situations: Empty plugin.yaml; concatenating multiple plugin manifests into one file; stray '---' creating extra documents; wrong kind/apiVersion document.
Related errors
- ESM provider manifest must contain format, entry, and option
- problemDetail.theme.install.missingManifest
- Invalid attachment
- User permissions not set in PermissionUtils
- ESM provider manifest must be an object.
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/1d85bcfd5a4b513c.
Report an issue: GitHub.