iOfficeAI/OfficeCLI · error · ArgumentException

Table name '{tableName}' collides with the workbook defined

Error message

Table name '{tableName}' collides with the workbook defined name '{dnName}'. Excel requires table and defined names to be unique in one namespace; choose a different table name.

What it means

Thrown by AddTable when the new table's Name or DisplayName collides with a workbook-level DefinedName. Excel places ListObjects and defined names in one namespace; although the collision passes OOXML schema validation, real Excel refuses the file with error 0x800A03EC. The handler iterates the workbook's DefinedNames and rejects any case-insensitive match up front.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs:1126

                throw new ArgumentException(
                    $"Table name '{tableName}' already exists in workbook; choose a different name.");
            if (string.Equals(existingTable.DisplayName?.Value, displayName, StringComparison.OrdinalIgnoreCase))
                throw new ArgumentException(
                    $"Table displayName '{displayName}' already exists in workbook; choose a different displayName.");
        }
        // Excel's name uniqueness spans ListObjects AND workbook defined
        // names in one namespace — a collision passes schema validation but
        // real Excel refuses the file (0x800A03EC).
        var definedNames = _doc.WorkbookPart.Workbook?.DefinedNames;
        if (definedNames != null)
        {
            foreach (var dn in definedNames.Elements<DefinedName>())
            {
                var dnName = dn.Name?.Value;
                if (dnName != null
                    && (string.Equals(dnName, tableName, StringComparison.OrdinalIgnoreCase)
                        || string.Equals(dnName, displayName, StringComparison.OrdinalIgnoreCase)))
                    throw new ArgumentException(
                        $"Table name '{tableName}' collides with the workbook defined name '{dnName}'. Excel requires table and defined names to be unique in one namespace; choose a different table name.");
            }
        }
        var styleName = properties.GetValueOrDefault("style", "TableStyleMedium2");
        // BUG-R9-B2: accept short aliases (medium2, light1, dark1, none) — schema
        // documents these but ValidateTableStyleName only accepted full names.
        styleName = NormalizeTableStyleName(styleName) ?? styleName;
        // T6 — validate style name against the built-in whitelist +
        // any workbook-level customStyles. Unknown names silently
        // fell through to Excel which would either ignore or
        // reject the file; prefer an explicit ArgumentException.
        ValidateTableStyleName(styleName);
        // T1 — accept `showHeader=false` alias alongside `headerRow=false`.
        var hasHeader = !(properties.TryGetValue("headerRow", out var hrVal) && !IsTruthy(hrVal))
                     && !(properties.TryGetValue("showHeader", out var shVal) && !IsTruthy(shVal));
        // CONSISTENCY(table-totalrow): accept `showTotals=true` alias
        // alongside `totalRow=true` (mirrors the `showHeader` alias
        // pattern above for users coming from Office API vocabulary).

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Choose a table name that does not match any existing defined name.
  2. Rename or remove the conflicting defined name first.
  3. Query the workbook's defined names before adding the table to pick a free name.

Example fix

// before (defined name 'SalesData' exists)
add /Sheet1/table --prop name=SalesData --prop ref=A1:D10
// after
add /Sheet1/table --prop name=SalesTable --prop ref=A1:D10
Defensive patterns

Strategy: validation

Validate before calling

// Check candidate table name against workbook defined names before Add.
static bool CollidesWithDefinedName(ExcelHandler h, string candidate)
{
    foreach (var dn in h.ListDefinedNames()) // pseudo
        if (string.Equals(dn, candidate, StringComparison.OrdinalIgnoreCase))
            return true;
    return false;
}

Try / catch

try { handler.Add(parentPath, "table", null, props); }
catch (ArgumentException ex) when (ex.Message.Contains("collides with the workbook defined name"))
{ /* rename the table or the defined name, then retry */ }

Prevention

When it happens

Trigger: Adding a table named 'SalesData' when a workbook defined name 'SalesData' already exists, or any name collision between the table Name/DisplayName and a DefinedName.

Common situations: Importing data that creates a defined name, then adding a table with the same label; or auto-generating table names that happen to match existing named ranges.

Related errors


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