paperclipai/paperclip · error
runner_provider_package_root_incompatible
runner_provider_package_root_incompatible
Error message
runner_provider_package_root_incompatible: ACPX sidecar must use the provider package dist/cli layout
What it means
acpxProviderPackageAuthority validates that the ACPX sidecar script path follows the strict provider-package layout <packageRoot>/dist/cli/acpx-runtime-sidecar.cjs. Anything else (source-tree script, renamed file, relocated install) is rejected because the code resolves the package root and dependency layout from that structure.
Source
Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:2724
throw new Error(
`runner_local_provider_artifact_missing: ${artifact} is absent; build @paperclipai/paperclip-runner TypeScript artifacts with build:typescript before starting a local JS-backed provider`,
);
}
function acpxProviderPackageAuthority(
sidecarScript: string,
ownerPackageRoot = packageRoot,
): {
root: string;
manifest: string;
} {
const cliDirectory = dirname(sidecarScript);
if (
basename(sidecarScript) !== "acpx-runtime-sidecar.cjs" ||
basename(cliDirectory) !== "cli" ||
basename(dirname(cliDirectory)) !== "dist"
) {
throw new Error(
"runner_provider_package_root_incompatible: ACPX sidecar must use the provider package dist/cli layout",
);
}
const sidecarPackageRoot = resolve(cliDirectory, "../..");
// A local source build lives at <workspace>/packages/paperclip-runner and
// resolves dependencies from <workspace>/node_modules. `pnpm deploy` makes
// the package itself the deployment root and owns <deploy>/node_modules/.pnpm.
// The older npm-installed portable shape nests the scoped package at
// <deploy>/node_modules/@paperclipai/paperclip-runner. The verifier always
// receives the directory that owns node_modules, regardless of which
// portable shape launched the already-authenticated sidecar.
const sourceDependencyRoot = resolve(ownerPackageRoot, "../..");
const localDependencyRoot = existsSync(
resolve(ownerPackageRoot, "node_modules", ".pnpm"),
)
? ownerPackageRoot
: basename(sourceDependencyRoot) === "node_modules"
? resolve(sourceDependencyRoot, "..")View on GitHub (pinned to 01ad858492)
Solutions
- Use the sidecar script at <providerPackageRoot>/dist/cli/acpx-runtime-sidecar.cjs exactly.
- Rebuild/redeploy the provider package (pnpm build / pnpm deploy) so the dist/cli layout exists.
- Do not rename or relocate the sidecar script; if packaging differs, restore the dist/cli directory structure.
- If resolving from a workspace, ensure resolution goes through node_modules to the deployed package, not the raw source path.
Example fix
// before
const sidecar = 'packages/acpx/src/acpx-runtime-sidecar.cjs';
// after
const sidecar = require.resolve('acpx-provider/dist/cli/acpx-runtime-sidecar.cjs'); Defensive patterns
Strategy: validation
Validate before calling
import { basename, dirname } from 'node:path';
const ok = basename(sidecar) === 'acpx-runtime-sidecar.cjs'
&& basename(dirname(sidecar)) === 'cli'
&& basename(dirname(dirname(sidecar))) === 'dist';
if (!ok) throw new Error('sidecar must live at <pkgRoot>/dist/cli/acpx-runtime-sidecar.cjs'); Type guard
const isDistCliSidecar = (p: string): boolean => basename(p) === 'acpx-runtime-sidecar.cjs' && basename(dirname(p)) === 'cli' && basename(dirname(dirname(p))) === 'dist';
Try / catch
try {
acpxProviderPackageAuthority(sidecar);
} catch (err) {
if ((err as Error).message.includes('runner_provider_package_root_incompatible')) {
sidecar = require.resolve('acpx-provider/dist/cli/acpx-runtime-sidecar.cjs');
} else throw err;
} Prevention
- Always resolve the sidecar with require.resolve, never relative paths
- Do not rename or copy the sidecar script out of dist/cli
- Validate packaging output in CI matches dist/cli layout
When it happens
Trigger: Passing a sidecarScript whose basename is not acpx-runtime-sidecar.cjs, whose parent directory is not named 'cli', or whose grandparent is not named 'dist' when constructing the ACPX provider transport.
Common situations: Pointing the sidecar at a source .ts/.cjs file during dev; a custom packaging step that emits to a different directory; symlinked or pnpm-store paths breaking the dist/cli shape; hand-copying the sidecar script elsewhere.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ACPX sidecar runtime context must be pre-materialized
- persisted Codex ACPX session identity is inconsistent
- ACPX runtime omitted acpxRecordId
- ACPX runtime omitted backendSessionId
- ACPX provider dependency ancestry is invalid
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/eb80b58148a63a5b.
Report an issue: GitHub.