microsoft/playwright-mcp · error · Error
Config type not found in config.d.ts
Error message
Config type not found in config.d.ts
What it means
update-readme.js embeds the user-facing Config type into README.md by reading `config.d.ts` (the published type definitions) and regex-extracting the `export type Config = { ... };` declaration. If that regex fails to match — because the declaration moved, was renamed, or its formatting changed — the script throws rather than generating an empty config section. It is a fragile-by-design check that surfaces drift between the script's expectations and the generated .d.ts bundle.
Source
Thrown at update-readme.js:225
const startMarker = `<!--- Options generated by ${path.basename(__filename)} -->`;
const endMarker = `<!--- End of options generated section -->`;
return updateSection(content, startMarker, endMarker, table);
}
/**
* @param {string} content
* @returns {Promise<string>}
*/
async function updateConfig(content) {
console.log('Updating config schema from config.d.ts...');
const configPath = path.join(__dirname, 'config.d.ts');
const configContent = await fs.promises.readFile(configPath, 'utf-8');
// Extract the Config type definition
const configTypeMatch = configContent.match(/export type Config = (\{[\s\S]*?\n\});/);
if (!configTypeMatch)
throw new Error('Config type not found in config.d.ts');
const configType = configTypeMatch[1]; // Use capture group to get just the object definition
const startMarker = `<!--- Config generated by ${path.basename(__filename)} -->`;
const endMarker = `<!--- End of config generated section -->`;
return updateSection(content, startMarker, endMarker, [
'```typescript',
configType,
'```',
]);
}
async function updateReadme() {
const readmePath = path.join(__dirname, 'README.md');
const readmeContent = await fs.promises.readFile(readmePath, 'utf-8');
const withTools = await updateTools(readmeContent);
const withOptions = await updateOptions(withTools);
const withConfig = await updateConfig(withOptions);View on GitHub (pinned to 16cf228d7b)
Solutions
- Regenerate the type definitions first (`npm run build` or whatever produces config.d.ts in utils/), then rerun `node utils/update-readme.js`.
- Inspect config.d.ts and confirm it still contains `export type Config = {` with the closing `};` on its own line; if the declaration shape changed (interface, intersection, union), update the regex in updateConfig (update-readme.js:~222) to match the new form.
- If Config was legitimately restructured, either restore a self-contained object literal type in the emitted d.ts or extend the extraction logic to handle the new syntax before rerunning the script.
Example fix
// before (config.d.ts) — closing brace not on its own line breaks the regex
export type Config = { browser: { launchOptions?: LaunchOptions } };
// after
export type Config = {
browser: {
launchOptions?: LaunchOptions;
};
}; Defensive patterns
Strategy: validation
Validate before calling
// Check the d.ts still exposes the expected declaration shape before generating:
import fs from 'fs';
const dts = fs.readFileSync('utils/config.d.ts', 'utf-8');
if (!/export type Config = (\{[\s\S]*?\n\});/.test(dts)) {
console.error('config.d.ts no longer contains a matchable `export type Config = { ... };` block — regenerate types or update the extraction regex.');
process.exit(1);
} Type guard
function hasExtractableConfigType(dtsContent) {
return /export type Config = (\{[\s\S]*?\n\});/.test(dtsContent);
} Try / catch
try {
content = await updateConfig(content);
} catch (e) {
if (/Config type not found in config\.d\.ts/.test(e.message)) {
console.warn('Skipping config section: config.d.ts shape changed.');
return content; // keep the previously generated config section
}
throw e;
} Prevention
- Always run the type-definition build step before update-readme.js in npm scripts.
- Keep the emitted Config as a plain object literal type (closing `};` on its own line) rather than an interface or intersection.
- Add a CI assertion that the regex in update-readme.js still matches the freshly built config.d.ts.
When it happens
Trigger: Running `node utils/update-readme.js` when config.d.ts no longer contains a literal `export type Config = {` ... `};` block — e.g. the type was renamed, extracted into an imported interface, made to extend another type, or the file wasn't regenerated after source changes so config.d.ts is missing or stale. The non-greedy regex `/(\{[\s\S]*?\n\});/` also fails if the closing brace is not at the start of a line (e.g. minified or differently formatted output).
Common situations: Refactoring src/config.ts so Config becomes an interface or a union; regenerating config.d.ts with a newer TypeScript compiler that formats the emitted declaration differently (e.g. `export type Config = { ... } & SharedOptions;`); running the script on a fresh clone before `npm run build` has produced config.d.ts; declaration emit bundling (api-extractor/dts-bundle) reordering or annotating the block with comments that break the `\n});` anchor.
Related errors
- Unknown tool capabilities: ${unknownCapabilities.join(', ')}
- Markers for generated section not found in README
AI-assisted analysis of microsoft/playwright-mcp@16cf228d7b (2026-08-27).
Data as JSON: /api/errors/8aff7a7e2684ef4d.
Report an issue: GitHub.