{"record":{"id":"ff61f152fb90c771","repo":"microsoft/playwright-mcp","slug":"unknown-tool-capabilities-unknowncapabilities-j","errorCode":null,"errorMessage":"Unknown tool capabilities: ${unknownCapabilities.join(', ')}. Please update the capabilities map in ${path.basename(__filename)}.","messagePattern":"Unknown tool capabilities: (.+?)\\. Please update the capabilities map in (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"update-readme.js","lineNumber":43,"sourceCode":"const capabilities = /** @type {Record<string, string>} */ ({\n  'core-navigation': 'Core automation',\n  'core': 'Core automation',\n  'core-tabs': 'Tab management',\n  'core-input': 'Core automation',\n  'core-install': 'Browser installation',\n  'config': 'Configuration',\n  'network': 'Network',\n  'storage': 'Storage',\n  'devtools': 'DevTools',\n  'vision': 'Coordinate-based',\n  'pdf': 'PDF generation',\n  'testing': 'Test assertions',\n});\n\nconst knownCapabilities = new Set(Object.keys(capabilities));\nconst unknownCapabilities = [...new Set(tools.browserTools.map(tool => tool.capability))].filter(cap => !knownCapabilities.has(cap));\nif (unknownCapabilities.length)\n  throw new Error(`Unknown tool capabilities: ${unknownCapabilities.join(', ')}. Please update the capabilities map in ${path.basename(__filename)}.`);\n\n/** @type {Record<string, any[]>} */\nconst toolsByCapability = {};\nfor (const capability of Object.keys(capabilities)) {\n  const title = capabilityTitle(capability);\n  let filteredTools = tools.browserTools.filter(tool => tool.capability === capability && !tool.skillOnly);\n  filteredTools = (toolsByCapability[title] || []).concat(filteredTools);\n  toolsByCapability[title] = filteredTools;\n}\nfor (const [, tools] of Object.entries(toolsByCapability))\n  tools.sort((a, b) => a.schema.name.localeCompare(b.schema.name));\n\n/**\n * @param {string} capability\n * @returns {string}\n */\nfunction capabilityTitle(capability) {\n  const title = capabilities[capability];","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/microsoft/playwright-mcp/blob/16cf228d7b02c07f800ec3423f471ec2a42d22a9/update-readme.js#L25-L61","documentation":"This error is thrown by utils/update-readme.js, the maintenance script that regenerates the README's tool tables from the manifest produced by the MCP server. Every browser tool declares a `capability` field, and the script keeps a hardcoded `capabilities` map (e.g. 'core', 'testing') that must enumerate every possible capability value. When a tool reports a capability not present in that map, the script aborts because it would otherwise silently drop that tool from the generated README.","triggerScenarios":"Running `node utils/update-readme.js` (or `npm run update-readme`) after adding a new tool to src/tools/*.ts whose `capability` string (e.g. capability: 'network') is not a key in the `capabilities` map at the top of update-readme.js. It also fires if an existing capability is renamed in the tool definition without updating the script, or if a tool's capability has a typo/case mismatch ('Core' vs 'core').","commonSituations":"Contributing a new browser tool or intercept tool to playwright-mcp; refactoring capability groupings (e.g. splitting 'core' into finer categories); copy-pasting a tool file and editing its capability field. Typically hit in CI or locally right after `npm run build` when regenerating docs.","solutions":["Add the new capability as a key in the `capabilities` map in utils/update-readme.js with a short description, and add a matching entry via `capabilityTitle()` if one is required.","Fix the tool definition: check the `capability` value on the tool named in the manifest and correct typos or casing so it matches an existing key such as 'core' or 'testing'.","If a capability was renamed intentionally, update both the tools and the capabilities map in the same commit, then rerun `node utils/update-readme.js` to confirm it passes."],"exampleFix":"// before (utils/update-readme.js)\nconst capabilities = {\n  'core': 'Core tools',\n  'testing': 'Test assertions',\n};\n\n// after — new tool declares capability: 'network'\nconst capabilities = {\n  'core': 'Core tools',\n  'testing': 'Test assertions',\n  'network': 'Network interception',\n};","handlingStrategy":"validation","validationCode":"// Before running the generator, verify every tool capability is known:\nimport { createServer } from '../src/index.js';\nimport fs from 'fs';\n\nconst script = fs.readFileSync('utils/update-readme.js', 'utf-8');\nconst known = [...script.matchAll(/^\\s*'([a-z-]+)':/gm)].map(m => m[1]);\nconst { tools } = await createServer(/* minimal config */).listTools();\nconst unknown = [...new Set(tools.map(t => t.capability))].filter(c => !known.includes(c));\nif (unknown.length) {\n  console.error('Update capabilities map first:', unknown.join(', '));\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  execSync('node utils/update-readme.js', { stdio: 'inherit' });\n} catch (e) {\n  if (/Unknown tool capabilities/.test(e.message ?? String(e))) {\n    // parse the capability list, add them to the capabilities map, rerun\n    throw new Error('README generator out of date: add missing capabilities to update-readme.js');\n  }\n  throw e;\n}","preventionTips":["When adding a tool or capability, update the capabilities map in update-readme.js in the same commit.","Keep capability strings as a single shared const/enum in src so tools and the script cannot drift.","Run `npm run update-readme` in CI to catch drift immediately rather than at release time."],"tags":["build-script","documentation-generation","developer-tooling","schema-mismatch"],"backgroundTag":"enum-value-not-in-allowed-set","analyzedSha":"16cf228d7b02c07f800ec3423f471ec2a42d22a9","analyzedAt":"2026-08-27T04:02:08.206Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}