denoland/deno · error

failed to parse {}: {e}

Error message

failed to parse {}: {e}

What it means

During tsconfig generation (`cli/tsc/tsconfig_gen.rs`), Deno reads the user's tsconfig as JSONC with `jsonc_parser`. An unparseable file is a hard `io::ErrorKind::InvalidData` failure — deliberately not degraded to `{}`, which would check with none of the user's options and report a misleading clean result. The message includes the file path and the parser's error detail `{e}` (line/column of the syntax error).

Source

Thrown at cli/tsc/tsconfig_gen.rs:63

/// `extends` and carries the npm project `references` - WITHOUT mutating the
/// user's file. `native_check` writes the returned value to a temp config in the
/// project root and points tsc at it, so the user's own options (including
/// path-based ones like `rootDirs`/`baseUrl` and any `include`/`files`) still
/// resolve relative to the project, exactly as if tsc read their file directly.
pub fn build_check_root_overlay(
  project_root: &Path,
  user_tsconfig_path: &Path,
) -> Result<Value, std::io::Error> {
  let content = std::fs::read_to_string(user_tsconfig_path)?;
  // An unparseable tsconfig is a hard error (matching `ensure_root_tsconfig`)
  // rather than silently degrading to `{}` - which would check with none of the
  // user's options and report a misleading clean.
  let parsed: Option<Value> = jsonc_parser::parse_to_serde_value(
    &content,
    &jsonc_parser::ParseOptions::default(),
  )
  .map_err(|e| {
    std::io::Error::new(
      std::io::ErrorKind::InvalidData,
      format!("failed to parse {}: {e}", user_tsconfig_path.display()),
    )
  })?;
  let mut value = parsed.unwrap_or_else(|| json!({}));
  if !value.is_object() {
    value = json!({});
  }

  // Read the generated config once (for its `types` and `references`).
  let deno_tsconfig = project_root.join(".deno").join("tsconfig.json");
  let deno_value = std::fs::read_to_string(&deno_tsconfig)
    .ok()
    .and_then(|t| serde_json::from_str::<Value>(&t).ok());

  {
    let obj = value.as_object_mut().unwrap();

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Open the printed path and fix the syntax error at the position given by `{e}` (e.g. `expected ',' or '}' at line N`).
  2. If the file is disposable, delete or rename it and re-run the command to regenerate from scratch.
  3. Add a JSONC parse check to CI lint so bad tsconfig never reaches the Deno command.

Example fix

# before
$ deno sync-types
# → failed to parse /repo/tsconfig.json: expected ',' or '}' at line 12 col 3

# after
$ $EDITOR tsconfig.json   # fix the syntax error at the reported position
$ deno sync-types
Defensive patterns

Strategy: validation

Validate before calling

# validate tsconfig parses as JSONC before running the command
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("failed to parse")) {
    // open the named file at the reported line/column and fix
  } else throw err;
}

Prevention

When it happens

Trigger: Running the command that generates/merges tsconfig state (e.g. `deno sync-types` and related flows) when the tsconfig.json at the printed path has a syntax error: unbalanced braces, stray tokens, truncation. Comments and trailing commas are fine — jsonc_parser accepts them.

Common situations: Hand-edited tsconfig with a typo; file truncated by a crashed editor or interrupted write; copy-paste from docs introducing smart quotes or stray characters.

Understand the failure class

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/e4e92274d6294190. Report an issue: GitHub.