halo-dev/halo · error · Error

${root} resolved to invalid version ${resolved.version} at $

Error message

${root} resolved to invalid version ${resolved.version} at ${resolved.packageRoot}. Install a valid published package or select IIFE output.

What it means

Thrown by validateResolvedSharedPackage when semver.parse() returns null for either the resolved shared package's version (read from the provider's installed package.json) or the host snapshot's version. The ESM provider build needs comparable semver versions to flag major mismatches between the plugin's bundled shared dependency and the Halo host. A non-semver version string (git URL, 'file:' link, '0.0.0' placeholder, workspace protocol) makes that comparison impossible, so the build aborts rather than emitting an uncomparable artifact.

Source

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

  return {
    name: packageJson.name,
    version: packageJson.version,
    packageRoot,
  };
}

export async function validateResolvedSharedPackage(
  root: SharedPackageRoot,
  providerRoot: string,
  snapshot: HaloHostRuntimeSnapshot,
  sourceId?: string
) {
  const resolved = await resolveSharedPackage(root, providerRoot, sourceId);
  const hostVersion = snapshot.packages[root].version;
  const resolvedVersion = parse(resolved.version);
  const parsedHostVersion = parse(hostVersion);
  if (!resolvedVersion || !parsedHostVersion) {
    throw new Error(
      `${root} resolved to invalid version ${resolved.version} at ${resolved.packageRoot}. ` +
        "Install a valid published package or select IIFE output."
    );
  }
  return {
    ...resolved,
    newerThanHost: compare(resolvedVersion, parsedHostVersion) > 0,
    differentMajor: resolvedVersion.major !== parsedHostVersion.major,
  };
}

export function isSharedPackageRoot(value: string): value is SharedPackageRoot {
  return sharedPackageRootSet.has(value);
}

function validateSnapshotEntry(
  root: SharedPackageRoot,
  value: unknown

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Run `npm ls <root>` (or pnpm why) for the offending root and replace any git/file/workspace link with a concrete published semver version, then reinstall.
  2. If you cannot pin a real version, select IIFE output (format: 'iife' or omit explicit esm) so the bundler skips version comparison entirely.
  3. Delete node_modules and the lockfile and reinstall to clear a stale yalc/linked package.json carrying a placeholder version.
  4. Verify the resolved package.json version with `node -e "console.log(require('semver').parse(require('<root>/package.json').version))"` before building.

Example fix

// before (package.json override)
"overrides": { "vue": "git+ssh://git@fork/vue.git" }

// after
"overrides": { "vue": "3.4.21" }
Defensive patterns

Strategy: validation

Validate before calling

import { parse } from "semver";
import { createRequire } from "node:module";
import { SHARED_PACKAGE_ROOTS } from "@halo-dev/ui-plugin-bundler-kit/runtime-snapshot";
const require = createRequire(import.meta.url);
for (const root of SHARED_PACKAGE_ROOTS) {
  let pkg;
  try { pkg = require(`${root}/package.json`); } catch { continue; }
  if (!parse(pkg.version)) {
    throw new Error(`Pre-build: ${root} resolved to non-semver version ${pkg.version}. Pin a real published version or use IIFE.`);
  }
}

Type guard

import { parse } from "semver";
function isStableSemver(value: unknown): value is string {
  return typeof value === "string" && parse(value) !== null && parse(value)!.prerelease.length === 0;
}

Prevention

When it happens

Trigger: An ESM build resolves one of SHARED_PACKAGE_ROOTS (vue, vue-router, pinia, axios, @formkit/vue, @formkit/core, @halo-dev/ui-shared, @halo-dev/components, @halo-dev/api-client, @halo-dev/richtext-editor) and the resolved package.json 'version' field is not parseable semver. Also fires if the matching host snapshot entry version is corrupt (unlikely, since snapshots are validated at load).

Common situations: Local dev with pnpm/yalc workspace-linked shared deps carrying version '0.0.0-use.local'; a git+ssh dependency override replacing a published package; a forked @halo-dev/components published with a non-semver tag; monorepo 'workspace:' protocol leaking into the resolved package.json.

Related errors


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