iOfficeAI/OfficeCLI · error · System.ArgumentException

phonetic requires a non-empty cell value (the base text the…

Error message

phonetic requires a non-empty cell value (the base text the phonetic guide annotates).

What it means

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.

Solutions

  1. Write the base text into the cell first (Set the cell value), then apply the phonetic guide.
  2. If the base text is a number, note that numeric cells use CellValue directly; ensure it is non-empty.
  3. Re-check that a prior operation did not blank the cell.

Example fix

// before
handler.Add("/Sheet1/A1", "phonetic", null, new() { ["text"] = "かんじ" }); // A1 empty

// after
handler.Set("/Sheet1/A1", "value", null, new() { ["value"] = "漢字" });
handler.Add("/Sheet1/A1", "phonetic", null, new() { ["text"] = "かんじ" });
Defensive patterns

Strategy: validation

Validate before calling

var cellInfo = handler.Query("/Sheet1/A1");
if (cellInfo == null || string.IsNullOrEmpty(cellInfo.Value))
    throw new InvalidOperationException("Cannot apply phonetic to an empty cell; set a value first");
handler.Add("/Sheet1/A1", "phonetic", null, props);

Type guard

static bool CellHasBaseText(CellInfo c) => !string.IsNullOrEmpty(c?.Value);

Try / catch

try { handler.Add("/Sheet1/A1", "phonetic", null, props); }
catch (ArgumentException ex) when (ex.Message.Contains("phonetic requires a non-empty cell value"))
{ /* set the base text first, then reapply */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/63a322690cf58d2b. Report an issue: GitHub.

Appendix: source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs:1603

    {
        // 1) Resolve the cell's base text.
        string baseText;
        if (cell.DataType?.Value == CellValues.SharedString
            && int.TryParse(cell.CellValue?.Text, out var existingIdx))
        {
            var existingSstPart = _doc.WorkbookPart?.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
            var existingSsi = existingSstPart?.SharedStringTable?
                .Elements<SharedStringItem>().ElementAtOrDefault(existingIdx);
            baseText = existingSsi?.Text?.Text
                ?? string.Concat(existingSsi?.Elements<Run>().Select(r => r.Text?.Text ?? "")
                    ?? Enumerable.Empty<string>());
        }
        else
        {
            baseText = cell.CellValue?.Text ?? "";
        }
        if (string.IsNullOrEmpty(baseText))
            throw new ArgumentException(
                "phonetic requires a non-empty cell value (the base text the phonetic guide annotates).");

        // 2) Build a fresh SSI: <si><t>baseText</t><rPh sb=0 eb=len><t>phonetic</t></rPh></si>
        var wbPart = _doc.WorkbookPart
            ?? throw new InvalidOperationException("Workbook not found");
        var sstPart = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()
            ?? wbPart.AddNewPart<SharedStringTablePart>();
        var sst = sstPart.SharedStringTable ??= new SharedStringTable();

        var ssi = new SharedStringItem(
            new Text(baseText) { Space = SpaceProcessingModeValues.Preserve });
        var rPh = new PhoneticRun(
                new Text(phoneticText) { Space = SpaceProcessingModeValues.Preserve })
        {
            BaseTextStartIndex = 0u,
            EndingBaseIndex = (uint)baseText.Length,
        };
        ssi.AppendChild(rPh);

View on GitHub (pinned to 1ced45e900)