microsoft/edit · error

Unexpected GCB={} with ExtPict=Y for U+{:04X} to U+{:04X}

Error message

Unexpected GCB={} with ExtPict=Y for U+{:04X} to U+{:04X}

What it means

The generator assumes every Extended_Pictographic codepoint has GCB=XX (Other) so it can alias ExtPict into the ClusterBreak enum with GB11 semantics. If a range has ExtPict=Y but a non-Other GCB, this invariant is broken and it bails rather than generating incorrect tables.

Source

Thrown at crates/unicode-gen/src/main.rs:820

                "L" => ClusterBreak::HangulL,        // Hangul Syllable Type L
                "V" => ClusterBreak::HangulV,        // Hangul Syllable Type V
                "T" => ClusterBreak::HangulT,        // Hangul Syllable Type T
                "LV" => ClusterBreak::HangulLV,      // Hangul Syllable Type LV
                "LVT" => ClusterBreak::HangulLVT,    // Hangul Syllable Type LVT
                _ => bail!(
                    "Unrecognized GCB={} for U+{:04X} to U+{:04X}",
                    char_attributes.grapheme_cluster_break,
                    range.start(),
                    range.end()
                ),
            };

            if char_attributes.extended_pictographic == "Y" {
                // Currently every single Extended_Pictographic codepoint happens to be GCB=XX.
                // This is fantastic for us because it means we can stuff it into the ClusterBreak enum
                // and treat it as an alias of EXTEND, but with the special GB11 properties.
                if cb != ClusterBreak::Other {
                    bail!(
                        "Unexpected GCB={} with ExtPict=Y for U+{:04X} to U+{:04X}",
                        char_attributes.grapheme_cluster_break,
                        range.start(),
                        range.end()
                    );
                }

                cb = ClusterBreak::ExtPic;
            }

            if !matches!(char_attributes.indic_conjunct_break, "None" | "Extend") {
                // If it's not None/Extend, it's Linker/Consonant, and currently
                // all of them are GCB=EX/XX. Since we treat them almost like extenders,
                // we need to revisit our assumptions if this ever changes.
                if !matches!(cb, ClusterBreak::Other | ClusterBreak::Extend) {
                    bail!(
                        "Unexpected GCB={} with InCB={} for U+{:04X} to U+{:04X}",
                        char_attributes.grapheme_cluster_break,

View on GitHub (pinned to 826b4c097b)

Solutions

  1. Use a consistent, supported set of UCD files from a single Unicode version.
  2. If a new Unicode release legitimately breaks the invariant, update the ClusterBreak modeling (no longer alias ExtPict into GCB) in the generator before regenerating.
  3. Check the comment-documented assumption in main.rs and adjust the GB11 handling accordingly.

Example fix

// before
if cb != ClusterBreak::Other { bail!("Unexpected GCB=... with ExtPict=Y") }
// after
// relax invariant: allow Extend with ExtPict=Y and handle GB11 explicitly
if !matches!(cb, ClusterBreak::Other | ClusterBreak::Extend) { bail!(...) }
Defensive patterns

Strategy: try-catch

Validate before calling

// verify ExtPict ranges align with GCB=XX before generating
download_pinned_ucd(VERSION); // single consistent version for all property files
verify_no_version_mixing(&["GraphemeBreakProperty.xml", "emoji-data.xml"], VERSION)?;

Try / catch

match generate(&ucd_path) {
    Err(e) if e.to_string().contains("with ExtPict=Y") => {
        eprintln!("ExtPict invariant broken — UCD version mismatch or unsupported release: {e}");
        std::process::exit(1);
    }
    r => r?,
}

Prevention

When it happens

Trigger: A future/patched Unicode release where a codepoint range is both Extended_Pictographic and carries a concrete GCB value (CR/LF/Control/Extend/etc.); or corrupted emoji-data/GraphemeBreakProperty inputs whose ranges misalign.

Common situations: Regenerating tables against a newer Unicode version whose emoji-data.txt assignments changed; mixing files from different Unicode versions so ExtPict and GCB data disagree.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of microsoft/edit@826b4c097b (2026-09-06). Data as JSON: /api/errors/8a948b585dcddfdc. Report an issue: GitHub.