{"record":{"id":"edd060994302b177","repo":"iOfficeAI/OfficeCLI","slug":"merge-range-refupper-overlaps-existing-merged","errorCode":null,"errorMessage":"Merge range '{refUpper}' overlaps existing merged range '{er}'. Excel rejects overlapping mergeCell entries.","messagePattern":"Merge range '(.+?)' overlaps existing merged range '(.+?)'\\. Excel rejects overlapping mergeCell entries\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Helpers.Cell.cs","lineNumber":286,"sourceCode":"            // corrupted a previously-fine file. Remove the empty shell\n            // before rethrowing.\n            if (!mergeCells.Elements<MergeCell>().Any() && mergeCells.Parent != null)\n                mergeCells.Remove();\n            throw;\n        }\n    }\n\n    private static void InsertMergeCellCheckedCore(MergeCells mergeCells, string newRangeRef, WorksheetPart? worksheetPart = null)\n    {\n        ValidateMergeRefLiteral(newRangeRef);\n        var refUpper = newRangeRef.ToUpperInvariant();\n        foreach (var existing in mergeCells.Elements<MergeCell>())\n        {\n            if (existing.Reference?.Value is not string er) continue;\n            var erUpper = er.ToUpperInvariant();\n            if (string.Equals(erUpper, refUpper, StringComparison.Ordinal)) return; // idempotent\n            if (RangesOverlap(refUpper, erUpper))\n                throw new ArgumentException(\n                    $\"Merge range '{refUpper}' overlaps existing merged range '{er}'. \" +\n                    $\"Excel rejects overlapping mergeCell entries.\");\n        }\n        // BUG-R2-table-merge BUG-5: Excel forbids mergeCell entries that\n        // intersect a ListObject table range — files saved with such a\n        // merge open with a \"found a problem\" repair dialog. Reject up\n        // front so callers see a clear error instead of file corruption.\n        if (worksheetPart != null)\n        {\n            foreach (var tdp in worksheetPart.TableDefinitionParts)\n            {\n                var tblRef = tdp.Table?.Reference?.Value;\n                if (string.IsNullOrEmpty(tblRef)) continue;\n                if (RangesOverlap(refUpper, tblRef.ToUpperInvariant()))\n                {\n                    var tblName = tdp.Table?.Name?.Value\n                        ?? tdp.Table?.DisplayName?.Value\n                        ?? \"(unnamed)\";","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Helpers.Cell.cs#L268-L304","documentation":"InsertMergeCellCheckedCore rejects a mergeCell whose range geometrically overlaps an existing merged range -- Excel itself rejects overlapping merges with a repair dialog, so this guard fails fast. The check is idempotent: an identical range is a silent no-op; only a true rectangle intersection throws. RangesOverlap is case-insensitive on the A1 refs. Fires from the Set/Add merge path (InsertMergeCellChecked wraps it and removes a now-empty <mergeCells> shell on failure).","triggerScenarios":"Merge A1:B2 then merge A2:B3 (shared cell A2/B2); merge B1:C1 then merge A1:B1 (shared B1); re-merge a sub-range of an existing merge that is not identical.","commonSituations":"Building a header layout incrementally and overlapping a prior merge; dump replay where the source had overlapping merges after manual editing; union of two adjacent merges that share an edge cell.","solutions":["Pick a disjoint range that does not intersect any existing merge.","Unmerge the conflicting existing range first, then re-merge the union.","Rely on idempotency: re-applying the exact same range is a no-op.","Enumerate current merges before applying and compute non-overlapping tiles."],"exampleFix":"// before -- A2 is already inside the A1:B2 merge\nset sheet!A1:B2 merge=true\nset sheet!A2:B3 merge=true  // throws: overlaps A1:B2\n\n// after -- unmerge first, then merge the union\nset sheet!A1:B2 merge=false\nset sheet!A1:B3 merge=true","handlingStrategy":"validation","validationCode":"// Before merging, ensure no existing merge overlaps the new range.\n// (Use the same RangesOverlap logic the library uses; re-derive existing merges via Get.)\nvar existing = handler.GetExistingMerges(sheet); // your helper\nforeach (var r in existing)\n    if (RangesOverlap(newRange, r) && !string.Equals(newRange, r, StringComparison.OrdinalIgnoreCase))\n        throw new InvalidOperationException($\"Would overlap existing merge {r}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enumerate existing merges before applying a new one.","Unmerge a conflicting range first, then re-merge the union.","Rely on idempotency -- re-applying the identical range is a no-op.","Build merge layouts as a set of disjoint tiles, never overlapping."],"tags":["excel","ooxml","merge","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}