{"record":{"id":"63a322690cf58d2b","repo":"iOfficeAI/OfficeCLI","slug":"phonetic-requires-a-non-empty-cell-value-the-base","errorCode":null,"errorMessage":"phonetic requires a non-empty cell value (the base text the phonetic guide annotates).","messagePattern":"phonetic requires a non-empty cell value \\(the base text the phonetic guide annotates\\)\\.","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":1603,"sourceCode":"    {\n        // 1) Resolve the cell's base text.\n        string baseText;\n        if (cell.DataType?.Value == CellValues.SharedString\n            && int.TryParse(cell.CellValue?.Text, out var existingIdx))\n        {\n            var existingSstPart = _doc.WorkbookPart?.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();\n            var existingSsi = existingSstPart?.SharedStringTable?\n                .Elements<SharedStringItem>().ElementAtOrDefault(existingIdx);\n            baseText = existingSsi?.Text?.Text\n                ?? string.Concat(existingSsi?.Elements<Run>().Select(r => r.Text?.Text ?? \"\")\n                    ?? Enumerable.Empty<string>());\n        }\n        else\n        {\n            baseText = cell.CellValue?.Text ?? \"\";\n        }\n        if (string.IsNullOrEmpty(baseText))\n            throw new ArgumentException(\n                \"phonetic requires a non-empty cell value (the base text the phonetic guide annotates).\");\n\n        // 2) Build a fresh SSI: <si><t>baseText</t><rPh sb=0 eb=len><t>phonetic</t></rPh></si>\n        var wbPart = _doc.WorkbookPart\n            ?? throw new InvalidOperationException(\"Workbook not found\");\n        var sstPart = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()\n            ?? wbPart.AddNewPart<SharedStringTablePart>();\n        var sst = sstPart.SharedStringTable ??= new SharedStringTable();\n\n        var ssi = new SharedStringItem(\n            new Text(baseText) { Space = SpaceProcessingModeValues.Preserve });\n        var rPh = new PhoneticRun(\n                new Text(phoneticText) { Space = SpaceProcessingModeValues.Preserve })\n        {\n            BaseTextStartIndex = 0u,\n            EndingBaseIndex = (uint)baseText.Length,\n        };\n        ssi.AppendChild(rPh);","sourceCodeStart":1585,"sourceCodeEnd":1621,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L1585-L1621","documentation":"Thrown by ApplyPhoneticToCell when the target cell has no base text to annotate. A phonetic guide (furigana/CJK ruby) overlays a reading on top of existing cell text, so an empty cell is rejected. Base text is resolved from a shared-string entry (for SharedString cells) or directly from CellValue; if both are empty/null, this fires.","triggerScenarios":"Calling Set/Add with type=phonetic on a cell that is blank, contains only whitespace resolved as empty, or whose shared-string index points to an empty SSI. Reachable after the cell is found, so the cell must exist but be empty.","commonSituations":"User applies the phonetic guide before writing the base text. The cell's value was cleared in a prior step. A shared-string index that is stale (points to a deleted/empty SSI).","solutions":["Write the base text into the cell first (Set the cell value), then apply the phonetic guide.","If the base text is a number, note that numeric cells use CellValue directly; ensure it is non-empty.","Re-check that a prior operation did not blank the cell."],"exampleFix":"// before\nhandler.Add(\"/Sheet1/A1\", \"phonetic\", null, new() { [\"text\"] = \"かんじ\" }); // A1 empty\n\n// after\nhandler.Set(\"/Sheet1/A1\", \"value\", null, new() { [\"value\"] = \"漢字\" });\nhandler.Add(\"/Sheet1/A1\", \"phonetic\", null, new() { [\"text\"] = \"かんじ\" });","handlingStrategy":"validation","validationCode":"var cellInfo = handler.Query(\"/Sheet1/A1\");\nif (cellInfo == null || string.IsNullOrEmpty(cellInfo.Value))\n    throw new InvalidOperationException(\"Cannot apply phonetic to an empty cell; set a value first\");\nhandler.Add(\"/Sheet1/A1\", \"phonetic\", null, props);","typeGuard":"static bool CellHasBaseText(CellInfo c) => !string.IsNullOrEmpty(c?.Value);","tryCatchPattern":"try { handler.Add(\"/Sheet1/A1\", \"phonetic\", null, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"phonetic requires a non-empty cell value\"))\n{ /* set the base text first, then reapply */ }","preventionTips":["Always set the cell's base value before applying a phonetic guide.","Query the cell to confirm non-empty content before the Add.","Order script steps so base-text writes precede phonetic writes."],"tags":["excel","ooxml","phonetic","ruby","empty-cell","argument"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}