{"record":{"id":"a045a55415875044","repo":"tui-cs/Terminal.Gui","slug":"only-a-single-grapheme-cluster-is-allowed-per-cell","errorCode":null,"errorMessage":"Only a single Grapheme cluster is allowed per Cell.","messagePattern":"Only a single Grapheme cluster is allowed per Cell\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Drawing/Cell.cs","lineNumber":32,"sourceCode":"    ///     Gets or sets a value indicating whether this <see cref=\"T:Terminal.Gui.Drawing.Cell\"/> has been modified since the\n    ///     last time it was drawn.\n    /// </summary>\n    public bool IsDirty { get; set; } = IsDirty;\n\n    private string _grapheme = Grapheme;\n\n    /// <summary>\n    ///     The single grapheme cluster to display from this cell. If <see cref=\"Grapheme\"/> is <see langword=\"null\"/> or\n    ///     <see cref=\"string.Empty\"/>, then <see cref=\"Cell\"/> is ignored.\n    /// </summary>\n    public string Grapheme\n    {\n        readonly get => _grapheme;\n        set\n        {\n            if (GraphemeHelper.GetGraphemeCount (value) > 1)\n            {\n                throw new InvalidOperationException ($\"Only a single {nameof (Grapheme)} cluster is allowed per Cell.\");\n            }\n\n            if (!string.IsNullOrEmpty (value) && value.Length == 1 && char.IsSurrogate (value [0]))\n            {\n                throw new ArgumentException ($\"Only valid Unicode scalar values are allowed in a single {nameof (Grapheme)} cluster.\");\n            }\n\n            try\n            {\n                _grapheme = !string.IsNullOrEmpty (value) && !value.IsNormalized (NormalizationForm.FormC)\n                                ? value.Normalize (NormalizationForm.FormC)\n                                : value;\n            }\n            catch (ArgumentException)\n            {\n                // leave text unnormalized\n                _grapheme = value;\n            }","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Drawing/Cell.cs#L14-L50","documentation":"Thrown by the Cell.Grapheme setter when the assigned string contains more than one grapheme cluster (as counted by GraphemeHelper.GetGraphemeCount). A Cell models exactly one screen column and therefore holds exactly one user-perceived character (grapheme); assigning a multi-grapheme string like \"ab\" or \"e\\u0301e\" violates that invariant.","triggerScenarios":"Directly assigning cell.Grapheme = \"ab\", or constructing new Cell { Grapheme = multiClusterString }, or a code path that pushes an unsplit string into a single Cell instead of a List<Cell>.","commonSituations":"Treating Cell like a general string holder; receiving user input and storing it in one cell instead of segmenting it; an off-by-one when slicing a string into cells.","solutions":["Use Cell.ToCellList(str, attribute) (or Cell.StringToCells) to split any string into one Cell per grapheme cluster — it uses GraphemeHelper.GetGraphemes internally.","If you must assign manually, verify GraphemeHelper.GetGraphemeCount(value) <= 1 first.","For combining sequences (base + combining marks), note those count as a SINGLE grapheme and are allowed; the error is only for 2+ clusters."],"exampleFix":"// before\nCell cell = new () { Grapheme = \"ab\" }; // throws\n\n// after\nList<Cell> cells = Cell.ToCellList (\"ab\"); // [Cell{a}, Cell{b}]","handlingStrategy":"validation","validationCode":"// Confirm at most one grapheme cluster before assigning\nif (GraphemeHelper.GetGraphemeCount (value) > 1)\n    throw new ArgumentException (\"Use Cell.ToCellList to split multi-grapheme strings.\");\ncell.Grapheme = value;","typeGuard":"static bool IsValidCellGrapheme (string s) => GraphemeHelper.GetGraphemeCount (s) <= 1;","tryCatchPattern":null,"preventionTips":["Always convert strings to cells via Cell.ToCellList / Cell.StringToCells instead of assigning raw.","Remember combining marks count as one grapheme and are allowed.","Add a debug assertion on GraphemeHelper.GetGraphemeCount in cell-building code."],"tags":["drawing","cell","unicode","grapheme"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}