paperclipai/paperclip · error · Error
Local filesystem/network confinement requires the Codex CLI
Error message
Local filesystem/network confinement requires the Codex CLI engine; ACP confinement is not supported.
What it means
Thrown by resolveCodexExecutionEngineForRun when the adapter config explicitly requests engine=acp (the Codex Agent Communication Protocol archive-staging lane) while also setting a filesystemScope or networkScope. ACP stages work in an archive and cannot apply spawn-level OS confinement, so the two settings are mutually exclusive and the resolver refuses to pick one silently.
Source
Thrown at packages/adapters/codex-local/src/server/acp.ts:106
legacyRemoteExecution: input.executionTransport?.remoteExecution,
});
if (target?.workspaceRealization?.mode === "in_place") {
if (selection.explicit && selection.engine === "acp") {
throw new Error("In-place workspace realization requires the Codex CLI engine; ACP archive staging is not supported.");
}
return {
engine: "cli",
explicit: selection.explicit,
...(!selection.explicit
? { fallbackReason: "In-place workspace realization must run without ACP archive staging." }
: {}),
};
}
const filesystemScope = parseLocalProcessFilesystemScope(input.config.filesystemScope);
const networkScope = parseLocalProcessNetworkScope(input.config.networkScope);
if (filesystemScope || networkScope) {
if (selection.explicit && selection.engine === "acp") {
throw new Error("Local filesystem/network confinement requires the Codex CLI engine; ACP confinement is not supported.");
}
return {
engine: "cli",
explicit: selection.explicit,
...(!selection.explicit
? { fallbackReason: "Local filesystem/network scope requires spawn-level confinement in the CLI lane." }
: {}),
};
}
if (selection.explicit || selection.engine !== "acp") return selection;
const fallbackReason = await defaultCodexAcpFallbackReason(input);
if (!fallbackReason) return selection;
return { engine: "cli", explicit: false, fallbackReason };
}
export function formatCodexAcpFallbackMessage(reason: string): string {
return `[paperclip] Codex ACP default unavailable; falling back to Codex CLI. ${reason} Set engine=acp to require ACP or engine=cli to silence this fallback.\n`;View on GitHub (pinned to 67001ec6eb)
Solutions
- If you need OS-level filesystem/network confinement, set config.engine to "cli" (or omit it so the resolver falls back to CLI with a fallbackReason) and keep the scopes.
- If you need ACP archive staging, remove the filesystemScope and networkScope fields from the adapter config so the confinement branch is not entered.
- If neither confinement nor ACP is strictly required, drop both engine and the scopes so the resolver can auto-pick ACP or fall back to CLI with a logged reason.
Example fix
// before
adapterConfig = { engine: "acp", filesystemScope: { root: "/workspace" } }
// after — confinement wins, CLI lane
adapterConfig = { engine: "cli", filesystemScope: { root: "/workspace" } } Defensive patterns
Strategy: validation
Validate before calling
function isCodexEngineConfigCoherent(cfg: { engine?: unknown; filesystemScope?: unknown; networkScope?: unknown }): boolean {
const engine = typeof cfg.engine === "string" ? cfg.engine.trim().toLowerCase() : "";
const explicit = engine === "acp" || engine === "cli";
const hasScope = cfg.filesystemScope != null || cfg.networkScope != null;
// ACP + scope is the rejected combination
return !(explicit && engine === "acp" && hasScope);
}
// call before starting the run
if (!isCodexEngineConfigCoherent(adapterConfig)) {
throw new Error("Refusing to start: engine=acp is incompatible with filesystemScope/networkScope.");
} Type guard
function isExplicitAcpWithScope(cfg: Record<string, unknown>): boolean {
const e = typeof cfg.engine === "string" ? cfg.engine.trim().toLowerCase() : "";
return e === "acp" && (cfg.filesystemScope != null || cfg.networkScope != null);
} Try / catch
try {
await resolveCodexExecutionEngineForRun(input);
} catch (e) {
if (e instanceof Error && /ACP confinement is not supported/.test(e.message)) {
// auto-downgrade to CLI lane, or surface a config error to the operator
input.config.engine = "cli";
} else throw e;
} Prevention
- Treat engine=acp and filesystemScope/networkScope as mutually exclusive in config schemas/UI validation.
- When copying a hardened CLI profile, clear the scopes or set engine=cli explicitly.
- Unit-test the engine resolver against all four (engine explicit/implicit) x (scope present/absent) combinations.
When it happens
Trigger: A run is started with config.engine explicitly set to "acp" (normalizeEngine maps the trimmed/lowercased value) AND parseLocalProcessFilesystemScope(config.filesystemScope) or parseLocalProcessNetworkScope(config.networkScope) returns a truthy scope. The in-place workspace realization branch (line 90) is NOT the one that fires here; this is the local confinement branch at line 104.
Common situations: Operator copies a hardened CLI-agent profile (which sets filesystemScope/networkScope for sandboxing) onto a company that was configured for ACP, or flips engine to acp to test archive staging without removing the confinement scopes they added for the CLI lane.
Related errors
- Local filesystem/network confinement requires the Claude CLI
- In-place workspace realization requires the Codex CLI engine
- Failed to parse JSON at ${filePath}: ${err instanceof Error
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/be77ca0957a651f0.
Report an issue: GitHub.