iOfficeAI/OfficeCLI · error · ArgumentException

Table displayName '{displayName}' already exists in workbook

Error message

Table displayName '{displayName}' already exists in workbook; choose a different displayName.

What it means

Thrown by AddTable's workbook-wide uniqueness check when a table with the same DisplayName (case-insensitive) already exists on any sheet. DisplayName (the ListObject name Excel shows in the UI and formula references) must be unique across the workbook alongside Name; a duplicate triggers a repair dialog. The check compares case-insensitively against every existing table's DisplayName.

Source

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

        var userProvidedDisplay = properties.ContainsKey("displayName");
        var displayName = SanitizeTableIdentifier(
            properties.GetValueOrDefault("displayName", tableName),
            userProvided: userProvidedDisplay || userProvidedName);

        // CONSISTENCY(table-name-unique): Excel requires both name and
        // displayName to be unique workbook-wide. A duplicate across
        // sheets surfaces a "found a problem" repair dialog. Walk every
        // WorksheetPart's tables, comparing case-insensitively.
        foreach (var existingTable in _doc.WorkbookPart!.WorksheetParts
            .SelectMany(wp => wp.TableDefinitionParts)
            .Select(tdp => tdp.Table)
            .Where(t => t != null)!)
        {
            if (string.Equals(existingTable!.Name?.Value, tableName, StringComparison.OrdinalIgnoreCase))
                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.");
            }
        }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Provide an explicit, unique displayName property.
  2. Remove or rename the conflicting existing table.
  3. Omit displayName so the handler derives it from a unique name.

Example fix

// before
add /Sheet2/table --prop name=Sales2 --prop displayName=Sales --prop ref=A1:D10
// after
add /Sheet2/table --prop name=Sales2 --prop displayName=Sales2 --prop ref=A1:D10
Defensive patterns

Strategy: validation

Validate before calling

// Reserve a workbook-unique displayName before Add (mirrors the 586 name check).
static string UniqueDisplayName(ExcelHandler h, string baseDisplay)
{
    var taken = new HashSet<string>(h.ListTableDisplayNames(), StringComparer.OrdinalIgnoreCase); // pseudo
    var d = baseDisplay; int i = 2;
    while (taken.Contains(d)) d = $"{baseDisplay}{i++}";
    return d;
}

Try / catch

try { handler.Add(parentPath, "table", null, props); }
catch (ArgumentException ex) when (ex.Message.Contains("displayName") && ex.Message.Contains("already exists"))
{ /* supply a unique displayName and retry */ }

Prevention

When it happens

Trigger: Adding a table whose computed or supplied DisplayName matches an existing table's DisplayName, e.g. when displayName collides because the name-derived display name was already taken.

Common situations: Two tables whose Name differs but whose DisplayName resolves to the same value, or explicitly setting a duplicate displayName property.

Related errors


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