{"record":{"id":"d8d0b0d08a7022c9","repo":"elsa-workflows/elsa-core","slug":"runtime-entity-audit-document-document-id-could-not-be","errorCode":null,"errorMessage":"Runtime entity audit document '{document.Id}' could not be deserialized.","messagePattern":"Runtime entity audit document '(.+?)' could not be deserialized\\.","errorType":"validation","errorClass":"DocumentStoreValidationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityManager.cs","lineNumber":244,"sourceCode":"        return indexValues;\n    }\n\n    private RuntimeEntityDefinition DeserializeDefinition(StoredDocument document)\n    {\n        return JsonSerializer.Deserialize<RuntimeEntityDefinition>(document.Content, _jsonOptions)\n            ?? throw new DocumentStoreValidationException($\"Runtime entity definition document '{document.Id}' could not be deserialized.\");\n    }\n\n    private RuntimeEntityInstance DeserializeInstance(StoredDocument document)\n    {\n        return JsonSerializer.Deserialize<RuntimeEntityInstance>(document.Content, _jsonOptions)\n            ?? throw new DocumentStoreValidationException($\"Runtime entity instance document '{document.Id}' could not be deserialized.\");\n    }\n\n    private RuntimeEntityAuditRecord DeserializeAudit(StoredDocument document)\n    {\n        return JsonSerializer.Deserialize<RuntimeEntityAuditRecord>(document.Content, _jsonOptions)\n            ?? throw new DocumentStoreValidationException($\"Runtime entity audit document '{document.Id}' could not be deserialized.\");\n    }\n\n    private static string NormalizeName(string name) => name.Trim().ToLowerInvariant();\n    private static string CreateInstanceDocumentId(string definitionName, string id) => $\"{NormalizeName(definitionName)}:{id}\";\n\n    private static string? ConvertIndexValue(object? value)\n    {\n        return value switch\n        {\n            null => null,\n            DateTimeOffset dateTimeOffset => dateTimeOffset.ToString(\"O\", CultureInfo.InvariantCulture),\n            DateTime dateTime => dateTime.ToUniversalTime().ToString(\"O\", CultureInfo.InvariantCulture),\n            IFormattable formattable => formattable.ToString(null, CultureInfo.InvariantCulture),\n            _ => value.ToString()\n        };\n    }\n}\n","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityManager.cs#L226-L262","documentation":"DeserializeAudit JSON-deserializes StoredDocument.Content into RuntimeEntityAuditRecord. A null result throws DocumentStoreValidationException naming the audit document id. Audit records are appended on every definition/instance mutation, so this indicates a stored audit entry that cannot be decoded.","triggerScenarios":"An audit document whose Content is null/empty/'null', was serialized with incompatible options (numeric enums, different naming policy), or was corrupted by external tooling or a failed migration.","commonSituations":"Reading audit trails after a serializer configuration change across versions; manual database cleanup; documents imported from another system; truncated writes during a crash.","solutions":["Inspect the audit document's Content and repair or drop the corrupt entry.","Align all writers on the same JsonSerializerOptions (Web defaults + JsonStringEnumConverter).","Rebuild audit history from instance/definition state if the records are unrecoverable."],"exampleFix":"// before\nvar audit = DeserializeAudit(doc); // throws on corrupt entry\n// after\ntry { var audit = DeserializeAudit(doc); }\ncatch (DocumentStoreValidationException ex) {\n    logger.LogWarning(ex, \"Skipping corrupt audit document {Id}\", doc.Id);\n    continue; // audit read is best-effort\n}","handlingStrategy":"try-catch","validationCode":"var doc = /* load StoredDocument */;\nif (string.IsNullOrWhiteSpace(doc.Content) || doc.Content == \"null\")\n    return null; // skip unusable audit entry","typeGuard":"bool IsValidAuditDocument(StoredDocument doc) =>\n    !string.IsNullOrWhiteSpace(doc.Content) && doc.Content != \"null\";","tryCatchPattern":"try { var audit = DeserializeAudit(doc); }\ncatch (DocumentStoreValidationException ex) { logger.LogWarning(ex, \"Skipping audit document {Id}\", doc.Id); }","preventionTips":["Treat audit reads as best-effort and skip corrupt entries rather than failing the whole trail.","Keep audit writers on the same serializer configuration as readers.","Include audit document integrity in backup/restore drills."],"tags":["persistence","serialization","audit","json"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}