dotnet/efcore · error · InvalidOperationException
'WithPartitionKey' can only be called once in a query. See h
Error message
'WithPartitionKey' can only be called once in a query. See https://aka.ms/efdocs-cosmos-partition-keys for more information.
What it means
Thrown when WithPartitionKey is invoked more than once in the same Cosmos query. The provider records partition key values into a single per-query list on the compilation context and disallows a second call, because combining multiple partition-key filters is not meaningful for a single Cosmos query and would produce ambiguous semantics.
Source
Thrown at src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs:170
translatedResponseContinuationTokenLimitInKb,
typeof(CosmosPage<>).MakeGenericType(shapedQuery.ShaperExpression.Type)))
.UpdateResultCardinality(ResultCardinality.Single);
}
return base.Translate(expression);
}
/// <inheritdoc />
protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
var method = methodCallExpression.Method;
if (methodCallExpression.Method.DeclaringType == typeof(CosmosQueryableExtensions)
&& methodCallExpression.Method.Name == nameof(CosmosQueryableExtensions.WithPartitionKey))
{
if (_queryCompilationContext.PartitionKeyPropertyValues.Count > 0)
{
throw new InvalidOperationException(CosmosStrings.WithPartitionKeyAlreadyCalled);
}
if (methodCallExpression.Arguments[0] is not EntityQueryRootExpression)
{
throw new InvalidOperationException(CosmosStrings.WithPartitionKeyBadNode);
}
var innerQueryable = Visit(methodCallExpression.Arguments[0]);
for (var i = 1; i < methodCallExpression.Arguments.Count; i++)
{
var value = _sqlTranslator.Translate(methodCallExpression.Arguments[i], applyDefaultTypeMapping: false);
if (value is not SqlConstantExpression and not SqlParameterExpression)
{
throw new InvalidOperationException(CosmosStrings.WithPartitionKeyNotConstantOrParameter);
}
_queryCompilationContext.PartitionKeyPropertyValues.Add(value);View on GitHub (pinned to dbf9771522)
Solutions
- Call WithPartitionKey exactly once per query, combining the relevant partition key values into a single call if multiple are supported.
- Refactor shared query-building helpers so partition key is applied at the outermost composition point only.
- If you need to switch partition keys, build a fresh queryable from the DbSet.
Example fix
// before
var q = context.Blogs.WithPartitionKey("tenantA").WithPartitionKey("region1");
// after
var q = context.Blogs.WithPartitionKey("tenantA", "region1"); Defensive patterns
Strategy: validation
Validate before calling
// Centralize partition key application and guard double-call
if (partitionKeyApplied) throw new InvalidOperationException("Partition key already set");
partitionKeyApplied = true;
var q = dbSet.WithPartitionKey(tenantId); Prevention
- Apply WithPartitionKey once, at the outermost query-composition point.
- Track whether a query builder already applied a partition key to avoid chaining.
- Document the single-call contract in helper methods that build Cosmos queries.
When it happens
Trigger: Chaining two WithPartitionKey calls on the same queryable, e.g. context.Blogs.WithPartitionKey("A").WithPartitionKey("B"). Also via composing queryables where each already applies a partition key.
Common situations: Helper methods that each add a partition key, accidentally composed. Migrating from a multi-key relational filter pattern to Cosmos partition keys.
Related errors
- 'WithPartitionKey' can only be called on an entity query roo
- 'WithPartitionKey' only accepts simple constant or parameter
- The partition key value is of type '{valueType}' which is no
- The partition key value supplied for '{propertyType}' proper
- The partition key properties for entity type '{entityType1}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/19111d9c266cd54a.
Report an issue: GitHub.