{"record":{"id":"433122f5e07bc21f","repo":"dotnet/orleans","slug":"azure-table-journal-row-entity-rowkey-property-433122","errorCode":null,"errorMessage":"Azure Table journal row \"{entity.RowKey}\" property \"{propertyName}\" is empty.","messagePattern":"Azure Table journal row \"(.+?)\" property \"(.+?)\" is empty\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs","lineNumber":925,"sourceCode":"            }\n\n            if (foundGap)\n            {\n                throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" contains a non-contiguous binary property \\\"{propertyName}\\\".\");\n            }\n\n            ReadOnlyMemory<byte> chunk = value switch\n            {\n                byte[] bytes => bytes,\n                BinaryData binaryData => binaryData.ToMemory(),\n                _ => throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" property \\\"{propertyName}\\\" is not a binary value.\"),\n            };\n\n            if (chunk.IsEmpty)\n            {\n                throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" property \\\"{propertyName}\\\" is empty.\");\n            }\n\n            foundChunk = true;\n            buffer.Write(chunk.Span);\n            length += chunk.Length;\n            consumer.Read(new JournalBufferReader(buffer.Reader, isCompleted: false), metadata);\n        }\n\n        if (!foundChunk)\n        {\n            throw new InvalidOperationException($\"Azure Table journal row \\\"{entity.RowKey}\\\" does not contain journal data.\");\n        }\n\n        return length;\n    }\n\n    private TableEntity CreateHeaderCountsPatch(HeaderProviderState providerState)","sourceCodeStart":907,"sourceCodeEnd":943,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs#L907-L943","documentation":"A DataNN chunk property exists on a journal row but contains an empty byte array. The writer loop (AzureTableJournalStorage.cs:868) only assigns a chunk while remaining data is non-empty, so an empty chunk should never be persisted. Its presence signals a corrupted or externally edited row.","triggerScenarios":"ReadChunks reads a DataNN property that deserializes to a zero-length byte[]/BinaryData and hits the chunk.IsEmpty guard at AzureTableJournalStorage.cs:923.","commonSituations":"An external editor cleared a property's bytes without deleting the key; a buggy custom migration wrote empty buffers; partial write under a non-transactional path left a placeholder empty value.","solutions":["Delete the malformed row (identified by RowKey in the message) and trigger a journal Replace to regenerate it.","Prevent any non-provider code from mutating DataNN properties.","If importing data, validate that every emitted chunk has length > 0 before writing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await journalStorage.ReadAsync(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"is empty\"))\n{\n    // Delete the offending row and Replace.\n}","preventionTips":["Never write empty byte arrays into DataNN slots.","Restrict table writes to the provider.","Validate imported data has non-empty chunks."],"tags":["azure-table","data-corruption","journal","chunks"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}