denoland/deno · error
existing {} is not valid JSON/JSONC: {e}. Fix or remove it a
Error message
existing {} is not valid JSON/JSONC: {e}. Fix or remove it and re-run `deno sync-types`. What it means
The ensure-root step of tsconfig generation refuses to touch an existing root tsconfig.json it cannot parse: `jsonc_parser::parse_to_ast` fails on the file's contents (comments and trailing commas allowed, so failures are real syntax errors). Because silently overwriting user content would destroy data, an unparseable file is a hard `InvalidData` error and the message instructs you to fix or remove it and re-run `deno sync-types`.
Source
Thrown at cli/tsc/tsconfig_gen.rs:322
.expect("failed to serialize tsconfig");
return std::fs::write(&root_tsconfig_path, &content);
}
// Parse as JSONC and edit the raw text by byte range (rather than
// re-serializing) so the user's comments and formatting are preserved. An
// unparseable file is a hard error rather than being silently overwritten.
use jsonc_parser::ast::ObjectPropName;
use jsonc_parser::ast::Value as JsoncValue;
let ast = jsonc_parser::parse_to_ast(
&content,
&jsonc_parser::CollectOptions {
comments: jsonc_parser::CommentCollectionStrategy::Off,
tokens: false,
},
&jsonc_parser::ParseOptions::default(),
)
.map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"existing {} is not valid JSON/JSONC: {e}. Fix or remove it and re-run \
`deno sync-types`.",
root_tsconfig_path.display()
),
)
})?;
let Some(JsoncValue::Object(obj)) = ast.value else {
// Not a JSON object (empty file, array, ...) — leave it alone.
return Ok(());
};
let extends = obj.properties.iter().find(|p| {
let name = match &p.name {
ObjectPropName::String(s) => s.value.as_ref(),
ObjectPropName::Word(w) => w.value,
};View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Inspect tsconfig.json for conflict markers (`<<<<<<<`/`=======`/`>>>>>>>`) or truncation and repair the syntax, then re-run `deno sync-types`.
- If the file is not precious, back it up or remove it and re-run — the command regenerates a valid one.
- Run `git diff --check` / a JSONC lint before syncing to catch damaged files early.
Example fix
# before $ deno sync-types # → existing /repo/tsconfig.json is not valid JSON/JSONC: ... # after (repair, or regenerate) $ git checkout -- tsconfig.json && deno sync-types $ rm tsconfig.json && deno sync-types
Defensive patterns
Strategy: validation
Validate before calling
# ensure the root tsconfig parses before deno sync-types
deno eval 'import { parse } from "jsr:@std/jsonc"; parse(Deno.readTextSync("tsconfig.json"));' Try / catch
try {
await runDeno("sync-types");
} catch (err) {
if (String(err).includes("not valid JSON/JSONC")) {
// fix the file, or rename it away and re-run to regenerate
} else throw err;
} Prevention
- Run git diff --check for conflict markers before syncing
- Commit only parseable tsconfig — add a CI parse step
- Back up custom tsconfig content before letting tooling rewrite it
When it happens
Trigger: Running `deno sync-types` when a root tsconfig.json already exists but contains unparseable content — typically unresolved git merge-conflict markers, encoding corruption, or a truncated write.
Common situations: Repos mid-rebase with conflict markers left in tsconfig.json; files damaged by a crash or partial save; committed files with non-UTF-8 bytes from a bad merge.
Related errors
- failed to parse {}: {e}
- Object is not a valid image or a path to an image. `Deno.jup
- Unknown attribute operator: '${s}'
- Expected token '${token}', but got '${this.token}'.\n\n${thi
- Invalid RegExp pattern: ${raw}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/c9a027fc20cb7889.
Report an issue: GitHub.