elsa-workflows/elsa-core · error · InvalidOperationException

SQLite physicalization supports dedicated relational tables…

Error message

SQLite physicalization supports dedicated relational tables only.

What it means

SqlitePhysicalizationPlanner.Plan can only generate a plan that maps each storage unit to its own dedicated relational table. When the physicalization policy requests any other target, the planner refuses because SQLite code generation in this module is implemented only for the DedicatedRelationalTable strategy.

Solutions

  1. Set policy.Target = PhysicalizationTarget.DedicatedRelationalTable before calling Plan.
  2. Use a different persistence provider package if you need non-dedicated-table physicalization targets.
  3. Guard the policy target in deployment code and switch providers or targets per database engine.

Example fix

// before
var policy = new StoragePhysicalizationPolicy { StorageUnit = "WorkflowInstances" };
var plan = planner.Plan(schema, policy);
// after
var policy = new StoragePhysicalizationPolicy { StorageUnit = "WorkflowInstances", Target = PhysicalizationTarget.DedicatedRelationalTable };
var plan = planner.Plan(schema, policy);
Defensive patterns

Strategy: validation

Validate before calling

if (policy.Target != PhysicalizationTarget.DedicatedRelationalTable)
    throw new ArgumentException($"SQLite requires Target=DedicatedRelationalTable, got {policy.Target}.", nameof(policy));

Try / catch

try { var plan = planner.Plan(schema, policy); }
catch (InvalidOperationException ex) when (ex.Message.Contains("dedicated relational tables only")) { /* fall back to a relational provider or fix target */ }

Prevention

When it happens

Trigger: Calling Plan(schema, policy) where policy.Target is set to anything other than PhysicalizationTarget.DedicatedRelationalTable, e.g. a default-constructed StoragePhysicalizationPolicy or one copied from a provider-agnostic config shared with other database backends.

Common situations: Reusing a physicalization policy object configured for a SQL Server/PostgreSQL provider that supports multiple targets; forgetting to set policy.Target explicitly so a non-SQLite default is used; running the same schema deployment code against multiple providers.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/aaaa449e423a83bf. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Persistence.VNext.Sqlite/Physicalization/SqlitePhysicalizationPlanner.cs:12

using System.Text.RegularExpressions;
using Elsa.Persistence.VNext;
using Elsa.Persistence.VNext.Physicalization;

namespace Elsa.Persistence.VNext.Sqlite.Physicalization;

public partial class SqlitePhysicalizationPlanner : IPhysicalizationPlanner
{
    public PhysicalizationPlan Plan(PersistenceSchema schema, StoragePhysicalizationPolicy policy)
    {
        if (policy.Target != PhysicalizationTarget.DedicatedRelationalTable)
            throw new InvalidOperationException("SQLite physicalization supports dedicated relational tables only.");

        var storageUnit = PhysicalizationPolicyValidator.GetStorageUnit(schema, policy);
        var tableName = Quote(policy.PhysicalName ?? policy.StorageUnit);
        var fieldColumns = storageUnit.Fields
            .Where(field => field.Name != "Id")
            .Select(field => $"    {Quote(field.Name)} TEXT NULL");
        var columns = string.Join(",\n", fieldColumns);
        var separator = string.IsNullOrWhiteSpace(columns) ? string.Empty : ",\n";
        var operations = new List<PhysicalizationOperation>
        {
            new(
                "CreateTable",
                $"Create dedicated SQLite table {tableName} for {policy.StorageUnit}.",
                $"""
                CREATE TABLE IF NOT EXISTS {tableName} (
                    Id TEXT NOT NULL PRIMARY KEY,
                    Content TEXT NOT NULL,
                    Version INTEGER NOT NULL,

View on GitHub (pinned to fe9217bdfa)