dotnet/orleans · error · ArgumentException

The journal id must not be the default value.

Error message

The journal id must not be the default value.

What it means

Thrown by AzureTableJournalStorageProvider.CreateStorage when the supplied JournalId is the default value. The provider cannot create a journal storage instance for an uninitialized id, since the partition key and all rows are keyed off the JournalId.

Source

Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorageProvider.cs:53

    private async Task Initialize(CancellationToken cancellationToken)
    {
        var createClient = _options.CreateClient
            ?? throw new InvalidOperationException(
                $"No Azure Table service client was configured. Set {nameof(AzureTableJournalStorageOptions.TableServiceClient)} " +
                $"or call {nameof(AzureTableJournalStorageOptions.ConfigureTableServiceClient)}.");
        var client = await createClient(cancellationToken).ConfigureAwait(false)
            ?? throw new InvalidOperationException("The configured Azure Table service client factory returned null.");
        var table = client.GetTableClient(_options.TableName);
        await table.CreateIfNotExistsAsync(cancellationToken).ConfigureAwait(false);
        _tableClientProvider.SetTableClient(table);
    }

    public IJournalStorage CreateStorage(JournalId journalId)
    {
        if (journalId.IsDefault)
        {
            throw new ArgumentException("The journal id must not be the default value.", nameof(journalId));
        }

        return new AzureTableJournalStorage(_shared, journalId);
    }

    public async IAsyncEnumerable<JournalId> ListAsync(
        JournalId prefix = default,
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        var table = _tableClientProvider.GetTableClient();
        var filter = TableClient.CreateQueryFilter($"RowKey eq {AzureTableJournalStorage.HeaderRowKey}");
        var journalIds = new List<JournalId>();
        await foreach (var entity in table.QueryAsync<TableEntity>(filter, select: JournalIdSelect, cancellationToken: cancellationToken))
        {
            if (TryGetJournalId(entity, out var journalId) && prefix.IsPrefixOf(journalId))
            {
                journalIds.Add(journalId);
            }

View on GitHub (pinned to fca799fa70)

Solutions

  1. Ensure the JournalId is constructed with a non-empty Value before calling CreateStorage.
  2. Guard the call site: if (journalId.IsDefault) return/skip.
  3. Trace where the default id originates (uninitialized field, missing constructor argument).

Example fix

// before
var storage = provider.CreateStorage(default(JournalId));
// after
if (journalId.IsDefault) throw new ArgumentException("id required", nameof(journalId));
var storage = provider.CreateStorage(journalId);
Defensive patterns

Strategy: validation

Validate before calling

if (journalId.IsDefault) throw new ArgumentException("id required", nameof(journalId));
var storage = provider.CreateStorage(journalId);

Type guard

static bool IsValidJournalId(JournalId id) => !id.IsDefault;

Prevention

When it happens

Trigger: Calling provider.CreateStorage(default) or passing a JournalId whose IsDefault is true (empty/unset Value).

Common situations: A journaled grain tries to open its storage before its id is assigned; test scaffolding passes default(JournalId); a deserialization step leaves the id default.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/c744c089b3cc27e1. Report an issue: GitHub.