{"record":{"id":"a8c1919f74c80bd8","repo":"ComposioHQ/composio","slug":"pass-either-sandbox-or-workbench-not-both-workbe","errorCode":null,"errorMessage":"Pass either sandbox or workbench, not both. workbench is a backwards-compatible alias for sandbox.","messagePattern":"Pass either sandbox or workbench, not both\\. workbench is a backwards-compatible alias for sandbox\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"warning","filePath":"ts/packages/core/src/lib/toolRouterParams.ts","lineNumber":123,"sourceCode":"  if (!parsedResult.success) {\n    throw new ValidationError('Failed to parse manage connections config', {\n      cause: parsedResult.error,\n    });\n  }\n\n  const config = parsedResult.data;\n  return {\n    enable: config.enable ?? true,\n    callback_url: config.callbackUrl,\n    enable_wait_for_connections: config.waitForConnections,\n  };\n};\n\nexport const resolveToolRouterSandboxConfig = (\n  config: Pick<ToolRouterCreateSessionConfig, 'sandbox' | 'workbench'>\n): ToolRouterCreateSessionConfig['sandbox'] | ToolRouterCreateSessionConfig['workbench'] => {\n  if (config.sandbox !== undefined && config.workbench !== undefined) {\n    throw new ValidationError(\n      'Pass either sandbox or workbench, not both. workbench is a backwards-compatible alias for sandbox.'\n    );\n  }\n  return config.sandbox ?? config.workbench;\n};\n\nexport const transformToolRouterSandboxParams = (\n  params?: ToolRouterCreateSessionConfig['sandbox'] | ToolRouterCreateSessionConfig['workbench']\n): SessionCreateParams.Workbench | undefined => {\n  if (!params) {\n    return undefined;\n  }\n\n  return {\n    enable: params.enable ?? true,\n    enable_proxy_execution: params.enableProxyExecution,\n    auto_offload_threshold: params.autoOffloadThreshold,\n    sandbox_size: params.sandboxSize,","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/lib/toolRouterParams.ts#L105-L141","documentation":"ValidationError: ToolRouter session creation accepts sandbox (and legacy alias workbench) but rejects passing both, since workbench is just a backwards-compatible rename. The guard prevents ambiguous configs where the two keys disagree.","triggerScenarios":"Calling createSession({ sandbox: {...}, workbench: {...} }); copy-pasted configs merging old code using workbench with new code using sandbox; spread-merging option objects that each define one key.","commonSituations":"Upgrading from versions that used workbench while keeping old defaults in a shared config object; LLM/agent-generated configs filling both fields.","solutions":["Delete one of the two keys — prefer sandbox (workbench is the alias)","If merging config objects, strip workbench before adding sandbox","Search the codebase for 'workbench' and migrate all uses to sandbox"],"exampleFix":"// before\nconfig({ sandbox: { runtime: 'bun' }, workbench: { runtime: 'bun' } })\n// after\nconfig({ sandbox: { runtime: 'bun' } })","handlingStrategy":"validation","validationCode":"const cfg = { ...(base ?? {}) };\ndelete cfg.workbench; // keep only sandbox","typeGuard":"const singleSandboxKey = (c: object): boolean =>\n  !('sandbox' in c && 'workbench' in c);","tryCatchPattern":"try { createSession(cfg); } catch (e) { if (e.message.includes('not both')) { delete cfg.workbench; createSession(cfg); } }","preventionTips":["Standardize on sandbox; grep for legacy workbench usage","Don't deep-merge configs that each define one alias"],"tags":["validation","tool-router","api-migration","sdk"],"backgroundTag":"mutually-exclusive-params","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}