{"record":{"id":"0560c72e7d534a1c","repo":"mastra-ai/mastra","slug":"invalid-browser-configuration-cdpurl-cannot-be","errorCode":null,"errorMessage":"Invalid browser configuration: \"cdpUrl\" cannot be used with ${conflicting}.\n\n• cdpUrl connects to an existing browser (which has its own profile and executable)\n• profile and executablePath are launch-time options for spawning a new browser\n\nTo fix this, either:\n1. Remove cdpUrl to launch a new browser with your profile/executable\n2. Remove profile/executablePath to connect to the existing browser via CDP","messagePattern":"Invalid browser configuration: \"cdpUrl\" cannot be used with (.+?)\\.\n\n• cdpUrl connects to an existing browser \\(which has its own profile and executable\\)\n• profile and executablePath are launch-time options for spawning a new browser\n\nTo fix this, either:\n1\\. Remove cdpUrl to launch a new browser with your profile/executable\n2\\. Remove profile/executablePath to connect to the existing browser via CDP","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/browser/browser.ts","lineNumber":648,"sourceCode":"    const scope = config.scope;\n    if (config.cdpUrl && scope === 'thread') {\n      throw new Error(\n        'Invalid browser configuration: \"cdpUrl\" and \"scope: \\'thread\\'\" cannot be used together.\\n\\n' +\n          '• cdpUrl connects to a single existing browser instance (all threads share it)\\n' +\n          '• scope: \"thread\" requires spawning separate browser instances per thread\\n\\n' +\n          'To fix this, either:\\n' +\n          '1. Remove cdpUrl to let the provider spawn separate browser instances (supports thread isolation)\\n' +\n          '2. Use scope: \"shared\" when connecting via cdpUrl (all threads share one browser)',\n      );\n    }\n\n    // Validate: cdpUrl is incompatible with launch-time options (profile, executablePath).\n    // CDP connects to an already-running browser — it has its own profile and executable.\n    if (config.cdpUrl && (config.profile || config.executablePath)) {\n      const conflicting = [config.profile && 'profile', config.executablePath && 'executablePath']\n        .filter(Boolean)\n        .join(' and ');\n      throw new Error(\n        `Invalid browser configuration: \"cdpUrl\" cannot be used with ${conflicting}.\\n\\n` +\n          '• cdpUrl connects to an existing browser (which has its own profile and executable)\\n' +\n          '• profile and executablePath are launch-time options for spawning a new browser\\n\\n' +\n          'To fix this, either:\\n' +\n          '1. Remove cdpUrl to launch a new browser with your profile/executable\\n' +\n          '2. Remove profile/executablePath to connect to the existing browser via CDP',\n      );\n    }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Lifecycle Management\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Launch the browser. Override in subclass.\n   * Called by launch() wrapper which handles status and race conditions.\n   */","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/browser/browser.ts#L630-L666","documentation":"cdpUrl connects to an already-running browser that carries its own profile and executable, so the launch-time options profile and executablePath make no sense alongside it. The constructor detects this conflict and throws with the list of conflicting options.","triggerScenarios":"Creating a Browser with cdpUrl set together with profile and/or executablePath in the same config object — e.g. merging a base launch config with a CDP override.","commonSituations":"Env-driven config where CDP_URL is provided but profile/executablePath defaults remain set; combining a local-Chrome config (executablePath) with a remote debugging URL; config spread/merge accidentally keeping stale launch options.","solutions":["Remove profile/executablePath from the config to connect to the existing browser via CDP.","Remove cdpUrl to launch a new browser with your profile/executable.","When merging configs, delete launch-time keys whenever cdpUrl is present."],"exampleFix":"// before\nconst browser = new Browser({\n  cdpUrl: 'http://127.0.0.1:9222',\n  executablePath: '/usr/bin/chromium', // conflict\n  profile: '/tmp/profile',             // conflict\n});\n// after\nconst browser = new Browser({ cdpUrl: 'http://127.0.0.1:9222' });","handlingStrategy":"validation","validationCode":"function sanitizeBrowserConfig(config) {\n  if (config.cdpUrl) {\n    const { profile, executablePath, ...rest } = config; // strip launch-time options\n    return rest;\n  }\n  return config;\n}\n// call site:\nconst browser = new Browser(sanitizeBrowserConfig(rawConfig));","typeGuard":"function isCdpCompatibleConfig(config) {\n  return !config.cdpUrl || (!config.profile && !config.executablePath);\n}","tryCatchPattern":"try {\n  browser = new Browser(config);\n} catch (e) {\n  if (e.message.includes('\"cdpUrl\" cannot be used with')) {\n    const { profile, executablePath, ...rest } = config;\n    browser = new Browser(rest); // prefer CDP connection\n  } else throw e;\n}","preventionTips":["Treat cdpUrl as an exclusive mode: when merging configs, delete profile/executablePath whenever cdpUrl is set.","Keep launch-time options and CDP options in separate config branches, never one flat object.","Add a unit test asserting sanitized configs for both CDP and launch modes."],"tags":["browser","configuration","cdp","validation"],"backgroundTag":"invalid-browser-config","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}