zed-industries/zed · error · anyhow::Error

failed to compile {} parser with clang: {}

Error message

failed to compile {} parser with clang: {}

What it means

The tree-sitter grammar compilation step failed: the builder invokes the wasi-sdk clang to compile the grammar's parser.c (plus scanner.c/.cc if present) to a wasm module exporting tree_sitter_{grammar_name}, and a non-zero clang exit status bails with clang's stderr. {grammar_name} identifies which grammar in the extension.toml [grammars] table failed.

Source

Thrown at crates/extension/src/extension_builder.rs:351

                "skipping compilation of {grammar_name} parser because the existing compiled grammar is up to date"
            );
        } else {
            log::info!("compiling {grammar_name} parser");
            let clang_output = util::command::new_command(&clang_path)
                .args(["-fPIC", "-shared", "-Os"])
                .arg(format!("-Wl,--export=tree_sitter_{grammar_name}"))
                .arg("-o")
                .arg(&grammar_wasm_path)
                .arg("-I")
                .arg(&src_path)
                .arg(&parser_path)
                .args(scanner_path.exists().then_some(scanner_path))
                .output()
                .await
                .context("failed to run clang")?;

            if !clang_output.status.success() {
                bail!(
                    "failed to compile {} parser with clang: {}",
                    grammar_name,
                    String::from_utf8_lossy(&clang_output.stderr),
                );
            }
        }

        Ok(())
    }

    async fn checkout_repo(&self, directory: &Path, url: &str, rev: &str) -> Result<()> {
        let git_dir = directory.join(".git");

        if directory.exists() {
            let remotes_output = util::command::new_command("git")
                .arg("--git-dir")
                .arg(&git_dir)
                .args(["remote", "get-url", "origin"])

View on GitHub (pinned to f4178619ac)

Solutions

  1. Read clang's stderr in the message - it names the file and line that failed
  2. Verify the pinned rev actually contains src/parser.c: clone the grammar repo, 'git checkout <rev>' and inspect src/
  3. If parser.c is missing, generate it with 'tree-sitter generate' upstream and pin to a rev that has it, or pick another rev
  4. Test-compile locally with the cached wasi-sdk clang using the same flags (-I src parser.c scanner.c -Wl,--export=tree_sitter_<name>) to iterate fast
  5. If clang itself failed (not the sources), clear the cached wasi-sdk dir under the extension builder cache to force a clean re-download
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the pinned rev has generated parser sources before building
let has_parser = std::path::Path::new(&format!("{cache}/{grammar}/src/parser.c")).exists();
anyhow::ensure!(has_parser, "grammar {grammar} has no src/parser.c at rev {rev}");

Try / catch

if let Err(err) = build_result {
    if err.to_string().contains("parser with clang") {
        // err contains clang stderr: file/line of the failing C source
        return Err(err.context("grammar C sources failed to compile - see clang diagnostics above"));
    }
    return Err(err);
}

Prevention

When it happens

Trigger: Running an extension build that includes grammars where clang rejects the C sources: missing generated parser.c at the pinned rev, scanner.c/scanner.cc errors, incompatible tree-sitter ABI (LANGUAGE_VERSION mismatch headers), clang running out of memory, or a broken/partial wasi-sdk in the cache.

Common situations: Grammar repo whose src/parser.c was never generated or was removed at the pinned commit; grammar written against a newer tree-sitter CLI than the vendored parser runtime; scanner using C++ features while being compiled as C; corrupted wasi-sdk download in the extension cache dir.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/450e07abd286fbe5. Report an issue: GitHub.