paperclipai/paperclip · error
ACPX provider package manifest must be an explicit normalize
Error message
ACPX provider package manifest must be an explicit normalized absolute path
What it means
createAcpxPackageJsonResolver also validates the manifest path (the provider package.json location, whether supplied explicitly or defaulted from root). It must be non-empty, absolute, null-byte-free, and already normalized (resolve(manifest) === manifest). This runs before realpathSync so the check fires on the literal path rather than on whatever the path symlinks to.
Source
Thrown at packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts:308
!root ||
!isAbsolute(root) ||
root.includes("\0") ||
resolve(root) !== root
) {
throw new Error(
"ACPX provider package root must be an explicit normalized absolute path",
);
}
const manifest = (
providerPackageManifest ?? resolve(root, "package.json")
).trim();
if (
!manifest ||
!isAbsolute(manifest) ||
manifest.includes("\0") ||
resolve(manifest) !== manifest
) {
throw new Error(
"ACPX provider package manifest must be an explicit normalized absolute path",
);
}
const canonicalRoot = realpathSync(root);
const canonicalManifest = realpathSync(manifest);
if (!pathIsInside(canonicalRoot, canonicalManifest)) {
throw new Error(
"ACPX provider package manifest resolves outside the selected provider root",
);
}
const canonicalNodeModules = realpathSync(
resolve(canonicalRoot, "node_modules"),
);
if (!pathIsInside(canonicalRoot, canonicalNodeModules)) {
throw new Error(
"ACPX provider node_modules resolves outside the selected provider root",
);
}View on GitHub (pinned to 01ad858492)
Solutions
- Convert the manifest to an absolute normalized path: path.resolve(root, 'package.json') before passing it in
- If the manifest is configured, store it as an absolute path at config-load time
- Sanitize/reject paths containing NUL bytes earlier, when reading user input
- Add a pre-call assertion: isAbsolute(m) && resolve(m) === m && !m.includes('\0')
Example fix
// before const resolver = createAcpxPackageJsonResolver(root, providerManifestPath); // './pkg/package.json' // after const manifest = path.resolve(root, providerManifestPath ?? 'package.json'); const resolver = createAcpxPackageJsonResolver(root, manifest);
Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path';
function normalizeManifest(root: string, manifest?: string): string {
const m = path.resolve(root, manifest ?? 'package.json');
if (m.includes('\0')) throw new Error('manifest path contains NUL byte');
return m;
} Type guard
function isValidManifestPath(p: unknown): p is string {
return typeof p === 'string' && p.length > 0 && path.isAbsolute(p) && !p.includes('\0') && path.resolve(p) === p;
} Try / catch
try {
const resolver = createAcpxPackageJsonResolver(root, manifestPath);
} catch (err) {
if (err instanceof Error && /manifest must be an explicit normalized absolute path/.test(err.message)) {
manifestPath = path.resolve(root, manifestPath ?? 'package.json');
return createAcpxPackageJsonResolver(root, manifestPath);
}
throw err;
} Prevention
- Derive the manifest from the root with path.resolve(root, 'package.json') instead of hand-built strings
- Never pass relative paths across module boundaries; normalize at the boundary
- Reject NUL bytes when reading paths from user/network input
- Add a test asserting all manifest-path fixtures are absolute and normalized
When it happens
Trigger: Passing providerPackageManifest as a relative path (e.g. 'package.json' or './pkg/package.json'), an empty string, a path containing '\0', or a non-normalized path like '/opt/acpx/provider/../provider/package.json'.
Common situations: Constructing the manifest path by string concatenation without path.resolve; storing a relative manifest path in config; importing a provider spec file that records the manifest relative to its own directory.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- ACPX provider package root must be an explicit normalized ab
- ACPX provider package manifest resolves outside the selected
- ACPX provider node_modules resolves outside the selected pro
- Select Codex to use the native Codex runner.
- OpenCode evals require exact version 1.18.17; received ${ver
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/cb47a42e45f38b8c.
Report an issue: GitHub.