OrchardCMS/OrchardCore · error · InvalidOperationException

The configured table name separator

Error message

The configured table name separator '{tableNameSeparator}' is invalid.

What it means

GetTableNameSeparator reads the shell setting 'TableNameSeparator' (or its default) and only accepts empty ('NULL' literal or empty => no separator) or strings composed solely of underscores. Any other character in the configured separator is rejected with InvalidOperationException, because table names are built by concatenating prefixes with this separator and invalid characters would corrupt SQL table names.

Solutions

  1. Set the separator to '_' (default), '__', or the literal string "NULL" for no separator.
  2. Remove invalid characters from TableNameSeparator in appsettings.json / tenant App_Data settings.
  3. Fix the DefaultTableNameSeparator in the shell configuration before tenant initialization.

Example fix

// before (appsettings.json)
"OrchardCore_Data_TableOptions": { "DefaultTableNameSeparator": "-" }
// after
"OrchardCore_Data_TableOptions": { "DefaultTableNameSeparator": "_" }  // or "NULL" for none
Defensive patterns

Strategy: validation

Validate before calling

var sep = config["OrchardCore_Data_TableOptions:DefaultTableNameSeparator"]?.Trim();
if (!string.IsNullOrEmpty(sep) && sep != "NULL" && sep.Any(c => c != '_'))
    throw new InvalidOperationException($"TableNameSeparator '{sep}' invalid; use '_' characters or 'NULL'.");

Type guard

bool IsValidSeparator(string s) { s = s?.Trim(); return string.IsNullOrEmpty(s) || s == "NULL" || s.All(c => c == '_'); }

Try / catch

try { var opts = shellSettings.GetDatabaseTableOptions(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("table name separator")) { _logger.LogCritical(ex, "Fix TableNameSeparator in tenant settings"); throw; }

Prevention

When it happens

Trigger: Configuring OrchardCore_Data_TableOptions:DefaultTableNameSeparator (appsettings.json or ShellSettings) with characters other than '_' or the literal 'NULL' — e.g. '-', '.', or a multi-character value like '__x' — then booting a tenant or calling GetDatabaseTableOptions().

Common situations: Copy-pasted config from another CMS using '-' separators; misunderstanding that only '_' or NULL are allowed; typos like '"__ "' with spaces (note settings are trimmed first).

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/951984d716b5401d. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Data.Abstractions/ShellSettingsExtensions.cs:66

    public static string GetTableNameSeparator(this ShellSettings shellSettings)
    {
        var tableNameSeparator = (!shellSettings.IsInitialized()
            ? shellSettings[DefaultTableNameSeparator]
            : shellSettings["TableNameSeparator"])
            ?.Trim();

        if (string.IsNullOrEmpty(tableNameSeparator))
        {
            tableNameSeparator = "_";
        }
        else if (tableNameSeparator == "NULL")
        {
            tableNameSeparator = string.Empty;
        }
        else if (tableNameSeparator.Any(c => c != '_'))
        {
            throw new InvalidOperationException($"The configured table name separator '{tableNameSeparator}' is invalid.");
        }

        return tableNameSeparator;
    }

    public static string GetIdentityColumnSize(this ShellSettings shellSettings)
    {
        var identityColumnSize = (!shellSettings.IsInitialized()
            ? shellSettings[DefaultIdentityColumnSize]
            : shellSettings["IdentityColumnSize"])
            ?.Trim();

        if (string.IsNullOrEmpty(identityColumnSize))
        {
            identityColumnSize = !shellSettings.IsInitialized() ? nameof(Int64) : nameof(Int32);
        }
        else if (!s_identityColumnSizes.Contains(identityColumnSize))
        {

View on GitHub (pinned to 4306c0717f)