paperclipai/paperclip · error · Error

OpenCode native backend requires an instance runtime directo

Error message

OpenCode native backend requires an instance runtime directory

What it means

createNativeSessionBackend wires up native session backends per provider. For the 'opencode' provider it needs a dedicated per-instance runtime directory where the OpenCode native backend stores its session/state files. If options.opencodeRuntimeDirectory is missing, empty, or whitespace-only, the factory refuses to build the backend and throws this error instead of creating a misconfigured session.

Source

Thrown at packages/paperclip-runner/src/backends/native-backend-factory.ts:54

 * Persisted contracts for future providers do not make those providers
 * executable before their independently reviewed runtime ships.
 */
export function createNativeSessionBackend(
  input: NativeExecutionInput,
  options: NativeBackendFactoryOptions = {},
): NativeSessionBackend {
  if (options.codexTransportFactory) {
    return createRunnerdNativeSessionBackend(input, {
      runnerInstanceId: options.runnerInstanceId,
      onSpawn: options.onSpawn,
      dynamicTools: options.dynamicTools,
      dynamicToolHandler: options.dynamicToolHandler,
      transportFactory: options.codexTransportFactory,
    });
  }
  if (input.provider.kind === "opencode") {
    if (!options.opencodeRuntimeDirectory?.trim()) {
      throw new Error(
        "OpenCode native backend requires an instance runtime directory",
      );
    }
    return createOpenCodeNativeSessionBackend(input, {
      runtimeDirectory: options.opencodeRuntimeDirectory,
      environment: options.opencodeEnvironment,
      command: options.opencodeCommand,
      runnerInstanceId: options.runnerInstanceId,
      onSpawn: options.onSpawn,
      dynamicTools: options.dynamicTools,
      dynamicToolHandler: options.dynamicToolHandler,
    });
  }
  if (input.provider.kind === "acpx") {
    if (input.provider.agent === "pi") {
      throw new Error(
        "Native ACPX backend for pi is unavailable until descriptor-confined verified launch is implemented",
      );

View on GitHub (pinned to 5716fe907e)

Solutions

  1. Set options.opencodeRuntimeDirectory to an absolute, existing directory path dedicated to this instance
  2. Verify the config source that populates opencodeRuntimeDirectory is actually supplying a value for opencode providers
  3. Trim/default the value at config-load time so it cannot arrive as '' or whitespace
  4. Only route opencode-provider sessions through this factory once the runtime directory is provisioned

Example fix

// before
const backend = createNativeSessionBackend(input, {
  dynamicToolHandler,
  codexTransportFactory,
});
// after
const backend = createNativeSessionBackend(input, {
  dynamicToolHandler,
  codexTransportFactory,
  opencodeRuntimeDirectory: "/var/lib/paperclip/instances/acme/opencode",
});
Defensive patterns

Strategy: validation

Validate before calling

function canCreateOpencodeBackend(options) {
  return typeof options.opencodeRuntimeDirectory === 'string' && options.opencodeRuntimeDirectory.trim().length > 0;
}
if (input.provider.kind === 'opencode' && !canCreateOpencodeBackend(options)) {
  throw new Error('opencodeRuntimeDirectory must be configured before creating an opencode native backend');
}

Type guard

function hasRuntimeDirectory(o) {
  return typeof o.opencodeRuntimeDirectory === 'string' && o.opencodeRuntimeDirectory.trim().length > 0;
}

Try / catch

let backend;
try {
  backend = createNativeSessionBackend(input, options);
} catch (err) {
  if (err.message.includes('instance runtime directory')) {
    throw new ConfigError('Set opencodeRuntimeDirectory in runner options before using the opencode provider', { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling createNativeSessionBackend with input.provider.kind === 'opencode' while options.opencodeRuntimeDirectory is undefined, an empty string, or a string of only whitespace.

Common situations: Operator config omits the opencode runtime directory setting; a templated config resolves the directory to an empty string; environment-specific wiring passes options through without the opencode block populated; a new instance was provisioned without its runtime directory being created/passed.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@5716fe907e (2026-09-02). Data as JSON: /api/errors/0fdf5399ce6d5a75. Report an issue: GitHub.