elsa-workflows/elsa-core · error · DocumentStoreValidationException

Runtime entity definition document

Error message

Runtime entity definition document '{document.Id}' could not be deserialized.

What it means

DeserializeDefinition JSON-deserializes the StoredDocument.Content into RuntimeEntityDefinition using web defaults with a string enum converter. A null result (e.g. content is the JSON literal 'null' or an empty payload) throws DocumentStoreValidationException with the document id, indicating stored data the reader cannot turn into a definition.

Solutions

  1. Inspect the offending document's Content in the store and repair or delete/rewrite it via SaveDraftAsync.
  2. Ensure documents are only written with matching JsonSerializerOptions (JsonSerializerDefaults.Web + JsonStringEnumConverter).
  3. Restore the document from backup or re-provision the definition, then re-publish.

Example fix

// before
var def = await manager.GetDefinitionAsync("orders"); // throws on corrupt doc
// after
try { var def = await manager.GetDefinitionAsync("orders"); }
catch (DocumentStoreValidationException ex) {
    logger.LogWarning(ex, "Corrupt definition document; re-provisioning");
    await manager.SaveDraftAsync(RebuildDefinition("orders"));
}
Defensive patterns

Strategy: try-catch

Validate before calling

var doc = /* load StoredDocument */;
if (string.IsNullOrWhiteSpace(doc.Content) || doc.Content == "null")
    throw new InvalidOperationException($"Definition document '{doc.Id}' has empty content.");

Type guard

bool IsValidDefinitionDocument(StoredDocument doc) =>
    !string.IsNullOrWhiteSpace(doc.Content) && doc.Content != "null";

Try / catch

try { var def = await manager.GetDefinitionAsync(name); }
catch (DocumentStoreValidationException ex) { logger.LogError(ex, "Corrupt definition document"); /* repair or re-provision */ }

Prevention

When it happens

Trigger: A stored definition document whose Content is null/empty/'null', was written by a different serializer configuration (e.g. numeric enums instead of string enums), or was corrupted/truncated externally.

Common situations: Manual database edits or migrations that wiped document content; switching serializer options between versions so old payloads no longer map; partial writes from a crashed process; reading documents written by another tool.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityManager.cs:232

            indexValues[$"Index{slot}Value"] = null;
        }

        for (var index = 0; index < definition.Indexes.Count; index++)
        {
            var indexedField = definition.Indexes[index].FieldName;
            instance.Data.TryGetValue(indexedField, out var value);
            var slot = index + 1;
            indexValues[$"Index{slot}Name"] = indexedField;
            indexValues[$"Index{slot}Value"] = ConvertIndexValue(value);
        }

        return indexValues;
    }

    private RuntimeEntityDefinition DeserializeDefinition(StoredDocument document)
    {
        return JsonSerializer.Deserialize<RuntimeEntityDefinition>(document.Content, _jsonOptions)
            ?? throw new DocumentStoreValidationException($"Runtime entity definition document '{document.Id}' could not be deserialized.");
    }

    private RuntimeEntityInstance DeserializeInstance(StoredDocument document)
    {
        return JsonSerializer.Deserialize<RuntimeEntityInstance>(document.Content, _jsonOptions)
            ?? throw new DocumentStoreValidationException($"Runtime entity instance document '{document.Id}' could not be deserialized.");
    }

    private RuntimeEntityAuditRecord DeserializeAudit(StoredDocument document)
    {
        return JsonSerializer.Deserialize<RuntimeEntityAuditRecord>(document.Content, _jsonOptions)
            ?? throw new DocumentStoreValidationException($"Runtime entity audit document '{document.Id}' could not be deserialized.");
    }

    private static string NormalizeName(string name) => name.Trim().ToLowerInvariant();
    private static string CreateInstanceDocumentId(string definitionName, string id) => $"{NormalizeName(definitionName)}:{id}";

    private static string? ConvertIndexValue(object? value)

View on GitHub (pinned to fe9217bdfa)