halo-dev/halo · warning · Error
Provider resource path escapes its root: ${resourcePath}.
Error message
Provider resource path escapes its root: ${resourcePath}. What it means
validateManifestResource requires the entry (and style) values in ui-plugin.json to be JSON strings. A non-textual node (number, object, array, boolean) throws this IllegalArgumentException, caught upstream and reported as ClassifiedProvider.invalid.
Source
Thrown at ui/packages/ui-plugin-bundler-kit/src/provider-manifest.ts:60
}
export function normalizeProviderResourcePath(resourcePath: string) {
const normalizedSlashes = resourcePath.replaceAll("\\", "/");
if (
!normalizedSlashes ||
normalizedSlashes.startsWith("/") ||
normalizedSlashes.startsWith("//") ||
/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(normalizedSlashes) ||
normalizedSlashes.includes("?") ||
normalizedSlashes.includes("#")
) {
throw new Error(
`Provider resource path must be provider-root-relative: ${resourcePath}.`
);
}
const normalized = path.posix.normalize(normalizedSlashes);
if (normalized === ".." || normalized.startsWith("../")) {
throw new Error(
`Provider resource path escapes its root: ${resourcePath}.`
);
}
return `./${normalized.replace(/^\.\//, "")}`;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
View on GitHub (pinned to d2f5165f9c)
Solutions
- Make entry and style plain string paths in ui-plugin.json.
- Point them at the actual file relative to the console/ provider root.
- Validate the manifest shape with a JSON schema in the build.
Example fix
// before
{
"format": "esm",
"entry": { "file": "index.js" }
}
// after
{
"format": "esm",
"entry": "index.js"
} Defensive patterns
Strategy: validation
Validate before calling
JsonNode entry = manifest.path("entry");
if (!entry.isTextual()) {
throw new IllegalStateException("ui-plugin.json entry must be a string path");
} Type guard
static boolean isStringPath(JsonNode n) { return n != null && n.isTextual() && StringUtils.hasText(n.asText()); } Prevention
- Keep entry/style as plain string paths.
- Do not nest paths inside objects.
- Validate types via JSON schema before packaging.
When it happens
Trigger: ui-plugin.json's entry or style is a non-string JSON value, e.g. "entry": 42 or "entry": {"src":"x.js"}.
Common situations: Author wraps the path in an object; build tool writes a numeric token; misconfigured manifest generator.
Related errors
- ESM provider manifest entry is required.
- ESM provider manifest style must be a string.
- Provider resource path must be provider-root-relative: ${res
- ESM UI provider output is missing its entry asset ${entryFil
- ESM UI provider output must contain exactly one entry JavaSc
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/7e4a537b45702a2e.
Report an issue: GitHub.