withastro/astro · error · Error
Unknown error parsing tsconfig.json or jsconfig.json. Could…
Error message
Unknown error parsing tsconfig.json or jsconfig.json. Could not update TypeScript settings.
What it means
After `astro add` installs an integration, it updates tsconfig.json/jsconfig.json (e.g. setting jsx settings for React). If the updater returns 'failure' — the config file exists but could not be parsed or written — astro add throws this generic Error from packages/astro/src/cli/add/index.ts:465 instead of corrupting your file silently.
Solutions
- Open tsconfig.json (and jsconfig.json if present) and fix JSON/JSONC syntax errors — validate by parsing it (`npx tsc --noEmit` or an editor's JSON validator)
- If the file is unrecoverable, back it up and regenerate a minimal tsconfig, then re-run `npx astro add <integration>`
- As a fallback, add the integration's required compilerOptions manually (see the integration's docs) — astro add will then skip or succeed
Example fix
```jsonc
// before: tsconfig.json (trailing comma)
{ "extends": "astro/tsconfigs/strict", }
// after
{ "extends": "astro/tsconfigs/strict" }
``` Defensive patterns
Strategy: try-catch
Validate before calling
// validate the config file parses before running astro add
import { readFileSync } from 'node:fs';
JSON.parse(readFileSync('tsconfig.json', 'utf8').replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:])\/\/.*$/gm, '$1'));
console.log('tsconfig.json parses ok'); Try / catch
try {
await add(['react'], { yes: true });
} catch (err) {
if (err instanceof Error && err.message.includes('Could not update TypeScript settings')) {
// add the jsx compilerOptions by hand, then continue
console.error('Fix tsconfig.json manually, then re-run astro add');
}
throw err;
} Prevention
- Run `npx tsc --noEmit` (or an editor JSON validator) after editing tsconfig
- Commit tsconfig before running astro add so failures are recoverable via git
When it happens
Trigger: Running `npx astro add react` (or similar) with a tsconfig.json containing invalid JSON/JSONC syntax; a config with stray trailing commas/comments that break the parser; file locked or with weird permissions; BOM or encoding issues; two config formats colliding (jsconfig.json and tsconfig.json both present).
Common situations: Hand-edited tsconfig with syntax errors; files written by other tools (editor plugins) with unusual formatting; monorepos sharing a base config with broken `extends`; a previous interrupted astro add leaving a malformed file.
Related errors
- Couldn't parse tsconfig.json or jsconfig.json
- Invalid package name
- expects a " " value!
- No problem! Find our official integrations at…
- doesn't appear to be an integration or an adapter. Find our…
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/77c4a2cdf142bae7.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/cli/add/index.ts:466
}
const updateTSConfigResult = await updateTSConfig(cwd, logger, integrations, flags, {
addIncludes: hasCloudflareIntegration ? ['./worker-configuration.d.ts'] : [],
});
switch (updateTSConfigResult) {
case 'none': {
break;
}
case 'cancelled': {
logger.info(
'SKIP_FORMAT',
msg.cancelled(`Your TypeScript configuration has ${bold('NOT')} been updated.`),
);
break;
}
case 'failure': {
throw new Error(
`Unknown error parsing tsconfig.json or jsconfig.json. Could not update TypeScript settings.`,
);
}
case 'updated':
logger.info('SKIP_FORMAT', msg.success(`Successfully updated tsconfig`));
}
}
function isAdapter(
integration: IntegrationInfo,
): integration is IntegrationInfo & { type: 'adapter' } {
return integration.type === 'adapter';
}
// Convert an arbitrary NPM package name into a JS identifier
// Some examples:
// - @astrojs/image => image
// - @astrojs/markdown-component => markdownComponentView on GitHub (pinned to e294953aa8)