microsoft/edit · error
Unexpected GCB={} with InCB={} for U+{:04X} to U+{:04X}
Error message
Unexpected GCB={} with InCB={} for U+{:04X} to U+{:04X} What it means
Indic_Conjunct_Break (InCB) values other than None/Extend are Linker/Consonant, which the generator assumes always co-occur with GCB=EX/XX (Extend or Other). If an InCB Linker/Consonant range has any other GCB, the assumption behind treating them like extenders fails and it bails.
Source
Thrown at crates/unicode-gen/src/main.rs:836
// 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,
char_attributes.indic_conjunct_break,
range.start(),
range.end()
);
}
cb = match char_attributes.indic_conjunct_break {
"Linker" => ClusterBreak::InCBLinker,
"Consonant" => ClusterBreak::InCBConsonant,
_ => bail!(
"Unrecognized InCB={} for U+{:04X} to U+{:04X}",
char_attributes.indic_conjunct_break,
range.start(),
range.end()
),
};
}View on GitHub (pinned to 826b4c097b)
Solutions
- Regenerate using a consistent UCD file set from the supported Unicode version.
- If a new release legitimately changes the co-occurrence, widen the matches! guard and update the extender modeling for InCB.
- Re-check the source UCD file if the combination looks like data corruption.
Example fix
// before
if !matches!(cb, ClusterBreak::Other | ClusterBreak::Extend) { bail!("Unexpected GCB=... with InCB=...") }
// after
// allow newly observed GCB for InCB Linker/Consonant
if !matches!(cb, ClusterBreak::Other | ClusterBreak::Extend | ClusterBreak::SpacingMark) { bail!(...) } Defensive patterns
Strategy: try-catch
Validate before calling
// ensure GraphemeBreakProperty and IndicConjunctBreak come from the same release
assert_eq!(ucd_version("GraphemeBreakProperty.xml"), ucd_version("IndicConjunctBreak.xml")); Try / catch
match generate(&ucd_path) {
Err(e) if e.to_string().contains("with InCB=") => {
eprintln!("InCB/GCB invariant broken — check Unicode version consistency: {e}");
std::process::exit(1);
}
r => r?,
} Prevention
- Regenerate InCB-aware tables only with the UCD release the generator was written for (Unicode 15.1+).
- Diff new InCB vs GCB co-occurrences before committing regenerated tables.
- Update the matches! guard deliberately when the Unicode spec changes, not silently.
When it happens
Trigger: A UCD release where a Linker/Consonant codepoint carries a GCB value other than Extend or Other; or mismatched UCD files where IndicConjunctBreak and GraphemeBreakProperty data come from different versions.
Common situations: Updating to a newer Unicode version (InCB was introduced in Unicode 15.1) without re-validating the assumptions; mixing GraphemeBreakProperty and IndicConjunctBreak files from different releases.
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
- Unexpected GCB={} with ExtPict=Y for U+{:04X} to U+{:04X}
- Unrecognized GCB={} for U+{:04X} to U+{:04X}
- Unrecognized InCB={} for U+{:04X} to U+{:04X}
- Unrecognized ea={} for U+{:04X} to U+{:04X}
AI-assisted analysis of microsoft/edit@826b4c097b (2026-09-06).
Data as JSON: /api/errors/1940eb78807189ff.
Report an issue: GitHub.