biomejs/biome · error

does not contain Unicode version

Error message

{} does not contain Unicode version {expected_version}

What it means

Validation error in xtask/codegen's Unicode data downloader. After fetching a Unicode data file (e.g. ScriptExtensions.txt), the `validate` method checks that the first 10 lines of the raw content mention the expected Unicode version; if not, it fails with the file path in the message. This guards against cached/stale/mismatched files whose version does not match what the generator was built for.

Solutions

  1. Clear the download cache (delete the cached file shown in the error, typically under the xtask cache/temp directory) and re-run to fetch fresh data.
  2. Verify the Unicode version constant in xtask matches the version of the data file being fetched; update the expected version or the URL together.
  3. Inspect the first lines of the file at the reported path to see what was actually downloaded; if it is an error page, fix network/proxy access.
  4. If the upstream file format changed its header, adjust the version constant or validation window in unicode.rs.

Example fix

# before: stale cached file from Unicode 15.0 while codegen expects 15.1
rm -rf ~/.cache/biome/unicode/
just gen-unicode  # re-downloads and validates the expected version
# after: validation passes with the freshly fetched 15.1 file
Defensive patterns

Strategy: validation

Validate before calling

// Verify a Unicode data file matches the expected version before feeding it to codegen
fn matches_version(path: &std::path::Path, expected: &str) -> anyhow::Result<()> {
    let head: String = std::fs::read_to_string(path)?
        .lines()
        .take(10)
        .collect::<Vec<_>>()
        .join("\n");
    anyhow::ensure!(head.contains(expected), "{} is not version {expected}", path.display());
    Ok(())
}

Try / catch

// Wrap the codegen invocation and handle version mismatch explicitly
match xtask::unicode::generate() {
    Err(e) if e.to_string().contains("does not contain Unicode version") => {
        eprintln!("stale/mismatched Unicode data: {e}; clear the cache and retry");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Running the Unicode codegen task (`xtask unicode` / related just commands) when the downloaded or cached file's header lines do not contain the expected version string passed by the caller.

Common situations: A stale cache from a previous Unicode version on disk; the upstream Unicode consortium replacing/renaming a file so headers changed; a mismatch between the version constant in the xtask source and the fetched URL; a proxy or mirror returning an HTML error page instead of the data file.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of biomejs/biome@3835945f06 (2026-09-13). Data as JSON: /api/errors/6a9cad8700fd1ffc. Report an issue: GitHub.

Appendix: source

Thrown at xtask/codegen/src/unicode.rs:214

    /// Return an error if reading cache or fetching fresh data from the unicode website fails.
    pub fn cached_or_fetch(
        cache_path: &'static str,
        source_url: &str,
        expected_version: &str,
        expected_size: usize,
    ) -> Result<Self> {
        Self::from_cache(cache_path)
            .and_then(|properties| properties.validate(expected_version, expected_size))
            .or_else(|_| {
                let fetched = Self::fetch(cache_path, source_url)?
                    .validate(expected_version, expected_size)?;
                fetched.save_cache()?;
                Ok(fetched)
            })
    }

    fn validate(self, expected_version: &str, expected_size: usize) -> Result<Self> {
        anyhow::ensure!(
            self.raw
                .lines()
                .take(10)
                .any(|line| line.contains(expected_version)),
            "{} does not contain Unicode version {expected_version}",
            self.path().display()
        );
        anyhow::ensure!(
            self.raw.len() == expected_size,
            "{} has size {}, expected {expected_size}",
            self.path().display(),
            self.raw.len()
        );

        Ok(self)
    }

    fn path(&self) -> PathBuf {

View on GitHub (pinned to 3835945f06)