dotnet/efcore · error · InvalidOperationException

Unable to generate a valid 'id' value to execute a…

Error message

Unable to generate a valid 'id' value to execute a 'ReadItem' query. This usually happens when the value provided for one of the properties is 'null' or an empty string. Provide a value that's not 'null' or an empty string.

What it means

When a query is optimized to a Cosmos ReadItem, EF builds the 'id' resource string from configured key property values via jsonIdDefinition.GenerateIdString. If the resulting id is null or empty (a constituent value was null or empty string) TryGetResourceId throws InvalidOperationException with InvalidResourceId.

Solutions

  1. Ensure all key property values contributing to the id are non-null and non-empty before issuing the lookup.
  2. Validate key inputs at the API boundary with a guard clause.
  3. If a key component legitimately may be empty, reconsider whether ReadItem optimization is appropriate (filter the property instead).

Example fix

// before
var u = await db.Users.FirstOrDefaultAsync(x => x.Id == maybeEmptyId);
// after
if (string.IsNullOrEmpty(maybeEmptyId)) throw new ArgumentException("Id required", nameof(maybeEmptyId));
var u = await db.Users.FirstOrDefaultAsync(x => x.Id == maybeEmptyId);
Defensive patterns

Strategy: validation

Validate before calling

static async Task<T?> GetByIdAsync<T>(DbSet<T> set, string id, CancellationToken ct)
    where T : class
{
    if (string.IsNullOrEmpty(id)) throw new ArgumentException("id required", nameof(id));
    return await set.FirstOrDefaultAsync(e => EF.Property<string>(e, "Id") == id, ct).ConfigureAwait(false);
}

Type guard

static bool IsValidResourceId(string? id) => !string.IsNullOrWhiteSpace(id);

Prevention

When it happens

Trigger: Querying for an entity by a key where one of the key property values is null or an empty string, so the generated document id is not a legal Cosmos resource id.

Common situations: Default/null key values on a partition key component, an empty string for the id property due to bad seed data, or a key property whose value comes from an unset request parameter.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/00db0f69609b8ecb. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs:94

            Check.DebugAssert(
                jsonIdDefinition != null,
                "Should not be using this enumerable if not using ReadItem, which needs an id definition.");

            var values = new List<object>(jsonIdDefinition.Properties.Count);
            foreach (var property in jsonIdDefinition.Properties)
            {
                var value = _readItemInfo.PropertyValues[property] switch
                {
                    SqlParameterExpression { Name: var parameterName } => _cosmosQueryContext.Parameters[parameterName],
                    SqlConstantExpression { Value: var constantValue } => constantValue,
                    _ => throw new UnreachableException()
                };

                values.Add(value);
            }

            resourceId = jsonIdDefinition.GenerateIdString(values);
            return string.IsNullOrEmpty(resourceId) ? throw new InvalidOperationException(CosmosStrings.InvalidResourceId) : true;
        }

        private sealed class AsyncEnumerator : IAsyncEnumerator<T>
        {
            private readonly CosmosQueryContext _cosmosQueryContext;
            private readonly string _cosmosContainer;
            private readonly PartitionKey _cosmosPartitionKey;
            private readonly Shaper<T> _shaper;
            private readonly Type _contextType;
            private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _queryLogger;
            private readonly bool _standAloneStateManager;
            private readonly IConcurrencyDetector _concurrencyDetector;
            private readonly IExceptionDetector _exceptionDetector;
            private readonly ReadItemQueryingEnumerable<T> _readItemEnumerable;
            private readonly CancellationToken _cancellationToken;

            private ReadOnlyMemory<byte>? _response;
            private bool _hasExecuted;

View on GitHub (pinned to 3a2006ef56)