stablyai/orca · error

[verify-skills-cli-runtime] import "${specifier}" from ${art

Error message

[verify-skills-cli-runtime] import "${specifier}" from ${artifactPath(outDir, importer)} resolved outside ${artifactRoot}: ${resolved}

What it means

resolveRuntimeImport() resolves a specifier successfully but isOutsideRoot(artifactRoot, resolved) returns true — the resolved file lives outside the artifact root. The verifier requires every runtime import to be self-contained within the artifact, so an escape (e.g. resolving into node_modules at the repo root, or the system) is a defect.

Source

Thrown at config/scripts/verify-skills-cli-runtime.cjs:99

function resolveRuntimeImport(outDir, artifactRoot, importer, specifier) {
  if (BUILTINS.has(specifier) || isBuiltin(specifier)) {
    return null
  }
  let resolved
  try {
    resolved = createRequire(importer).resolve(specifier)
  } catch (error) {
    if (isOptionalPackageImport(artifactRoot, importer, specifier)) {
      return null
    }
    const detail = error instanceof Error ? error.message : String(error)
    throw new Error(
      `[verify-skills-cli-runtime] missing runtime import "${specifier}" from ` +
        `${artifactPath(outDir, importer)}: ${detail}`
    )
  }
  if (isOutsideRoot(artifactRoot, resolved)) {
    throw new Error(
      `[verify-skills-cli-runtime] import "${specifier}" from ` +
        `${artifactPath(outDir, importer)} resolved outside ${artifactRoot}: ${resolved}`
    )
  }
  return resolved
}

function collectRuntimeClosure(outDir, artifactRoot = dirname(outDir)) {
  outDir = realpathSync(outDir)
  artifactRoot = realpathSync(artifactRoot)
  if (isOutsideRoot(artifactRoot, outDir)) {
    throw new Error(`[verify-skills-cli-runtime] ${outDir} is outside ${artifactRoot}`)
  }
  const entry = resolve(outDir, 'cli', 'index.js')
  if (!existsSync(entry)) {
    throw new Error(`[verify-skills-cli-runtime] missing entry ${entry}`)
  }
  const pending = [entry]

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect the resolved path in the message — if it's in a node_modules outside the artifact, the dep must be bundled rather than left external.
  2. Remove the offending package from the bundler's externals, or vendor it under the artifact root.
  3. Confirm artifactRoot passed to collectRuntimeClosure is the directory that will actually ship.
  4. If realpath symlinking causes a false escape, ensure the artifact is built and resolved without crossing the boundary.
Defensive patterns

Strategy: validation

Validate before calling

// Before running the closure walk, confirm artifactRoot is correct and contains outDir:
import { realpathSync } from 'node:fs'
function assertContained(child, root) {
  const c = realpathSync(child), r = realpathSync(root)
  if (c !== r && !c.startsWith(r + path.sep)) {
    throw new Error(`${child} resolves outside artifact root ${root}`)
  }
}
assertContained(outDir, artifactRoot)

Prevention

When it happens

Trigger: A dependency was marked external and resolves to the repo's top-level node_modules instead of being bundled; a relative import climbs above the artifact root with ../; the artifact root passed to collectRuntimeClosure is wrong (too narrow).

Common situations: Bundler externals list too aggressive; symlinks that realpath above the artifact root; artifactRoot path computation off-by-one (dirname vs the actual publish dir); dep hoisting in a monorepo putting the file outside the package.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/c25285d6f7cbb939. Report an issue: GitHub.