iOfficeAI/OfficeCLI · error · System.ArgumentException

'col' property is required for colbreak

Error message

'col' property is required for colbreak

What it means

Thrown by AddColBreak when none of the col, column, or index properties are present in the properties dictionary. The lookup chains GetValueOrDefault for all three aliases and throws if all return null. A column break requires a target column, so omitting it is unrecoverable.

Source

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

        SaveWorksheet(rbWorksheet);

        var rbIdx = rowBreaks.Elements<Break>().ToList()
            .FindIndex(b => b.Id?.Value == rbRowIdx) + 1;
        return $"/{rbSheetName}/rowbreak[{rbIdx}]";
    }

    private string AddColBreak(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)
    {
        var index = position?.Index;
        var cbSegments = parentPath.TrimStart('/').Split('/', 2);
        var cbSheetName = cbSegments[0];
        var cbWorksheet = FindWorksheet(cbSheetName)
            ?? throw new ArgumentException($"Sheet not found: {cbSheetName}");
        var cbWs = GetSheet(cbWorksheet);

        var cbColStr = properties.GetValueOrDefault("col") ?? properties.GetValueOrDefault("column")
            ?? properties.GetValueOrDefault("index")
            ?? throw new ArgumentException("'col' property is required for colbreak");
        // Accept both numeric index (e.g. "3") and column letter (e.g. "C")
        var cbColIdx = uint.TryParse(cbColStr, out var cbNumVal)
            ? cbNumVal
            : (uint)ColumnNameToIndex(cbColStr.ToUpperInvariant());
        // Same schema Min/Max guard as rowbreak: 0 / beyond-XFD ids write
        // invalid OOXML that only surfaces at validate/open time.
        if (cbColIdx < 1 || cbColIdx > 16384)
            throw new ArgumentException(
                $"Invalid 'col' value: '{cbColStr}'. Column breaks must be between 1 and 16384 (A-XFD).");

        var colBreaks = cbWs.GetFirstChild<ColumnBreaks>();
        if (colBreaks == null)
        {
            colBreaks = new ColumnBreaks();
            cbWs.AppendChild(colBreaks);
        }
        // Optional restricted row span (min/max) — mirrors the Set path.
        var cbBreak = new Break { Id = cbColIdx, Max = 1048575u, ManualPageBreak = true };

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Add a col property: properties["col"]="C" (letter) or "3" (numeric).
  2. column and index are accepted aliases.
  3. If you meant a row break, use type=rowbreak with row= instead.

Example fix

// before
handler.Add("/Sheet1", "colbreak", null, new() { ["min"] = "1" });

// after
handler.Add("/Sheet1", "colbreak", null, new() { ["col"] = "C", ["min"] = "1" });
Defensive patterns

Strategy: validation

Validate before calling

if (!props.ContainsKey("col") && !props.ContainsKey("column") && !props.ContainsKey("index"))
    throw new InvalidOperationException("colbreak requires 'col', 'column', or 'index'");
handler.Add("/Sheet1", "colbreak", null, props);

Type guard

static bool HasColbreakTarget(IReadOnlyDictionary<string,string> p)
    => p.ContainsKey("col") || p.ContainsKey("column") || p.ContainsKey("index");

Prevention

When it happens

Trigger: Add type=colbreak with a properties dictionary lacking col/column/index (e.g. only min/max, or empty). If col is present but empty, ColumnNameToIndex later throws rather than this guard. This throw specifically requires all three keys absent.

Common situations: User copies a rowbreak command and forgets to change row to col. Conditional property construction where the col branch is skipped. Assuming the position's Index supplies the column (it does not for colbreak).

Related errors


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