paperclipai/paperclip · error
Environment driver "${driver.driver}" does not support duple
Error message
Environment driver "${driver.driver}" does not support duplex channels. What it means
Thrown by the environment runtime's openDuplexChannel facade when the resolved driver for the lease does not implement openDuplexChannel (server/src/services/environment-runtime.ts:3474). Driver support is optional: only the plugin-backed sandbox driver provides duplex channels today; drivers like the local process driver expose syncOut/execute only. The check mirrors the native file sync guard above it ("does not support native file sync").
Source
Thrown at server/src/services/environment-runtime.ts:3474
throw new Error(`Environment driver "${driver.driver}" does not support native file sync.`);
}
return await driver.syncIn(input);
},
async syncOut(input: EnvironmentDriverSyncInput): Promise<PluginEnvironmentSyncResult> {
const driver = requireDriverKey(getLeaseDriverKey(input.lease, input.environment));
if (!driver.syncOut) {
throw new Error(`Environment driver "${driver.driver}" does not support native file sync.`);
}
return await driver.syncOut(input);
},
async openDuplexChannel(
input: EnvironmentDriverOpenDuplexChannelInput,
): Promise<CommandManagedDuplexChannel> {
const driver = requireDriverKey(getLeaseDriverKey(input.lease, input.environment));
if (!driver.openDuplexChannel) {
throw new Error(`Environment driver "${driver.driver}" does not support duplex channels.`);
}
// Centralize the duplex channel authorization here. Resolve the exact lease
// capability snapshot and refuse unless the effective snapshot grants the
// opt-in `duplexCommandStream` capability. This gate runs before the driver
// call, so an unauthorized lease never reaches the worker. The
// execution-target member gate stays as defense in depth. A driver that
// cannot resolve the snapshot fails closed with the fixed refusal.
const effective =
(await driver.effectiveSandboxCapabilities?.(input)) ?? null;
if (effective?.duplexCommandStream !== true) {
throw new Error(DUPLEX_CHANNEL_CAPABILITY_DENIED);
}
return await driver.openDuplexChannel(input);
},
};
}
export type EnvironmentRuntimeService = ReturnType<typeof environmentRuntimeService>;View on GitHub (pinned to a7e689b3c3)
Solutions
- Feature-detect before calling: check typeof driver.openDuplexChannel === "function" or gate on the lease being a plugin sandbox lease.
- Use the driver's supported execution path (execute) when duplex is unavailable.
- Provision the environment with the plugin sandbox provider driver if duplex streaming is required.
- For custom drivers, implement openDuplexChannel (and effectiveSandboxCapabilities) to opt into the feature.
Example fix
// before
const ch = await envRuntime.openDuplexChannel({ lease, environment, command }); // throws for local driver
// after
const duplexSupported = typeof getDriver(getLeaseDriverKey(lease, environment))?.openDuplexChannel === "function";
if (!duplexSupported) {
await envRuntime.execute({ lease, environment, command });
} else {
const ch = await envRuntime.openDuplexChannel({ lease, environment, command });
} Defensive patterns
Strategy: type-guard
Validate before calling
const driverKey = getLeaseDriverKey(lease, environment);
const driver = requireDriverKey(driverKey);
if (typeof driver.openDuplexChannel !== "function") { return await runtime.execute({ lease, environment, command }); } Type guard
function driverSupportsDuplex(driver: { openDuplexChannel?: unknown }): boolean {
return typeof driver.openDuplexChannel === "function";
} Try / catch
try { return await runtime.openDuplexChannel(input); } catch (err) { if (/does not support duplex channels/.test((err as Error).message)) { return await runtime.execute(input); /* degrade to one-shot */ } throw err; } Prevention
- Feature-detect driver capabilities instead of assuming all environments support duplex streaming.
- Provision plugin sandbox environments when interactive command streams are required.
- Keep driver capability checks next to call sites so unsupported drivers degrade gracefully.
When it happens
Trigger: Calling openDuplexChannel on the runtime facade for a lease whose driver key resolves to a driver without an openDuplexChannel method — e.g. a local/docker environment lease, or a plugin sandbox driver instantiated without a pluginWorkerManager.
Common situations: Code written against plugin sandboxes run against local dev environments; a custom driver registered without duplex support; attempting interactive streaming against a driver that only supports one-shot execute.
Related errors
- Sandbox driver does not support duplex channels for this lea
- Managed installs require Node.js ${MINIMUM_NODE_VERSION} or
- Managed worktree seed registration is incomplete; project wo
- The duplex channel launch command needs at least one argumen
- Daytona duplex channel: no cached sandbox resolves the provi
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21).
Data as JSON: /api/errors/fbc48e17530ae3db.
Report an issue: GitHub.