{"record":{"id":"d4d235fe237fa1d2","repo":"microsoft/playwright","slug":"error-params-option-expected-a-json-object-received-params","errorCode":null,"errorMessage":"error: '--params' option: expected a JSON object, received '${params}'","messagePattern":"error: '--params' option: expected a JSON object, received '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/cli-daemon/commands.ts","lineNumber":1283,"sourceCode":"const tray = declareCommand({\n  name: 'tray',\n  description: 'Run tray',\n  category: 'config',\n  hidden: true,\n  toolName: '',\n  toolParams: () => ({}),\n});\n\n// WebMCP\n\nfunction parseWebMCPParams(params: string | undefined) {\n  if (params === undefined)\n    return undefined;\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(params);\n  } catch (e) {\n    throw new Error(`error: '--params' option: expected a JSON object, received '${params}'`);\n  }\n  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))\n    throw new Error(`error: '--params' option: expected a JSON object, received '${params}'`);\n  return parsed as Record<string, unknown>;\n}\n\nconst webmcpList = declareCommand({\n  name: 'webmcp-list',\n  description: 'List the WebMCP tools registered by the page',\n  category: 'webmcp',\n  args: z.object({}),\n  toolName: 'browser_webmcp_list',\n  toolParams: () => ({}),\n});\n\nconst webmcpCall = declareCommand({\n  name: 'webmcp-call',\n  description: 'Call a WebMCP tool registered by the page',","sourceCodeStart":1265,"sourceCodeEnd":1301,"githubUrl":"https://github.com/microsoft/playwright/blob/f1d33b5029be8bbc1095fe88e559117fa3a6243b/packages/playwright-core/src/tools/cli-daemon/commands.ts#L1265-L1301","documentation":"The CLI daemon's --params option must parse to a JSON object. This throw site handles JSON.parse failures: the provided string is not syntactically valid JSON, so the command aborts with a formatted error. The helper returns undefined when --params is absent, so this only fires when a value was supplied.","triggerScenarios":"Passing --params with malformed JSON, e.g. --params \"{tool:'x'}\" (single quotes / unquoted keys) or unescaped quotes in the shell that get stripped before parsing.","commonSituations":"Shell quoting stripping double quotes (--params {\"tool\":\"x\"} becomes {tool:x}); writing JS object literals instead of JSON; Windows cmd quoting differences.","solutions":["Quote the whole value in single quotes in POSIX shells: --params '{\"tool\":\"x\",\"input\":\"{}\"}'.","Validate the string with JSON.parse (e.g. node -e \"JSON.parse(process.argv[1])\") before passing it.","Avoid --params entirely if no parameters are needed (it is optional)."],"exampleFix":"// before (shell strips quotes)\nwebmcp-call --params {\"name\":\"get-weather\"}\n// after\nwebmcp-call --params '{\"name\":\"get-weather\"}'","handlingStrategy":"validation","validationCode":"function isJsonObjectString(s) {\n  if (s === undefined) return true;\n  try { const v = JSON.parse(s); return typeof v === 'object' && v !== null && !Array.isArray(v); } catch { return false; }\n}\n// assert before invoking the CLI","typeGuard":null,"tryCatchPattern":"try {\n  await runCli(['webmcp-call', '--params', paramsStr]);\n} catch (e) {\n  if (e.message.includes(\"'--params' option\")) throw new Error(`Bad --params: ${paramsStr}. Use single-quoted strict JSON object.`);\n  throw e;\n}","preventionTips":["Always single-quote --params values in POSIX shells.","Use JSON.stringify(obj) in scripts instead of hand-written JSON.","Validate with JSON.parse before invoking the CLI."],"tags":["cli","json","argument-parsing"],"backgroundTag":"invalid-cli-argument","analyzedSha":"f1d33b5029be8bbc1095fe88e559117fa3a6243b","analyzedAt":"2026-09-15T07:37:15.003Z","contentChangedAt":"2026-09-15T07:37:15.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}