{"record":{"id":"be77ca0957a651f0","repo":"paperclipai/paperclip","slug":"local-filesystem-network-confinement-requires-the-be77ca","errorCode":null,"errorMessage":"Local filesystem/network confinement requires the Codex CLI engine; ACP confinement is not supported.","messagePattern":"Local filesystem/network confinement requires the Codex CLI engine; ACP confinement is not supported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapters/codex-local/src/server/acp.ts","lineNumber":106,"sourceCode":"    legacyRemoteExecution: input.executionTransport?.remoteExecution,\n  });\n  if (target?.workspaceRealization?.mode === \"in_place\") {\n    if (selection.explicit && selection.engine === \"acp\") {\n      throw new Error(\"In-place workspace realization requires the Codex CLI engine; ACP archive staging is not supported.\");\n    }\n    return {\n      engine: \"cli\",\n      explicit: selection.explicit,\n      ...(!selection.explicit\n        ? { fallbackReason: \"In-place workspace realization must run without ACP archive staging.\" }\n        : {}),\n    };\n  }\n  const filesystemScope = parseLocalProcessFilesystemScope(input.config.filesystemScope);\n  const networkScope = parseLocalProcessNetworkScope(input.config.networkScope);\n  if (filesystemScope || networkScope) {\n    if (selection.explicit && selection.engine === \"acp\") {\n      throw new Error(\"Local filesystem/network confinement requires the Codex CLI engine; ACP confinement is not supported.\");\n    }\n    return {\n      engine: \"cli\",\n      explicit: selection.explicit,\n      ...(!selection.explicit\n        ? { fallbackReason: \"Local filesystem/network scope requires spawn-level confinement in the CLI lane.\" }\n        : {}),\n    };\n  }\n  if (selection.explicit || selection.engine !== \"acp\") return selection;\n\n  const fallbackReason = await defaultCodexAcpFallbackReason(input);\n  if (!fallbackReason) return selection;\n  return { engine: \"cli\", explicit: false, fallbackReason };\n}\n\nexport function formatCodexAcpFallbackMessage(reason: string): string {\n  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`;","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapters/codex-local/src/server/acp.ts#L88-L124","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nadapterConfig = { engine: \"acp\", filesystemScope: { root: \"/workspace\" } }\n// after — confinement wins, CLI lane\nadapterConfig = { engine: \"cli\", filesystemScope: { root: \"/workspace\" } }","handlingStrategy":"validation","validationCode":"function isCodexEngineConfigCoherent(cfg: { engine?: unknown; filesystemScope?: unknown; networkScope?: unknown }): boolean {\n  const engine = typeof cfg.engine === \"string\" ? cfg.engine.trim().toLowerCase() : \"\";\n  const explicit = engine === \"acp\" || engine === \"cli\";\n  const hasScope = cfg.filesystemScope != null || cfg.networkScope != null;\n  // ACP + scope is the rejected combination\n  return !(explicit && engine === \"acp\" && hasScope);\n}\n// call before starting the run\nif (!isCodexEngineConfigCoherent(adapterConfig)) {\n  throw new Error(\"Refusing to start: engine=acp is incompatible with filesystemScope/networkScope.\");\n}","typeGuard":"function isExplicitAcpWithScope(cfg: Record<string, unknown>): boolean {\n  const e = typeof cfg.engine === \"string\" ? cfg.engine.trim().toLowerCase() : \"\";\n  return e === \"acp\" && (cfg.filesystemScope != null || cfg.networkScope != null);\n}","tryCatchPattern":"try {\n  await resolveCodexExecutionEngineForRun(input);\n} catch (e) {\n  if (e instanceof Error && /ACP confinement is not supported/.test(e.message)) {\n    // auto-downgrade to CLI lane, or surface a config error to the operator\n    input.config.engine = \"cli\";\n  } else throw e;\n}","preventionTips":["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."],"tags":["codex","acp","confinement","config","engine-selection"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}