dotnet/efcore · error · ArgumentOutOfRangeException

A FromSqlExpression has an invalid arguments expression type

Error message

A FromSqlExpression has an invalid arguments expression type '{expressionType}' or value type '{valueType}'.

What it means

FromSqlRaw/FromSqlInterpolated on Cosmos only accepts argument shapes that the provider can flatten into literal substitutions: a ConstantExpression holding a parameter array or raw values. If the Arguments node is a different Expression subtype the switch falls through to the default case and throws ArgumentOutOfRangeException, reporting the offending expression type and (if constant) its value type.

Solutions

  1. Pass arguments as a plain object[] to FromSqlRaw or use FromSqlInterpolated with an interpolated string.
  2. Verify the parameter array element types each have a Cosmos type mapping (avoid unsupported CLR types).
  3. Do not wrap the FromSql root in additional LINQ operators that rewrite the Arguments expression; project after the root instead.

Example fix

// before
var rows = db.Users.FromSqlRaw("SELECT * FROM c WHERE c.id = {0}", idScalar);
// after
var rows = db.Users.FromSqlRaw("SELECT * FROM c WHERE c.id = {0}", new object[] { idScalar });
Defensive patterns

Strategy: validation

Validate before calling

static IQueryable<T> SafeFromSql<T>(DbSet<T> set, string sql, params object[] args)
    where T : class
{
    if (args is null || Array.TrueForAll(args, a => a is null || a.GetType().IsPrimitive || a is string || a is DateTime || a is Guid))
        return set.FromSqlRaw(sql, args ?? Array.Empty<object>());
    throw new ArgumentException("FromSqlRaw arguments must be simple constants.", nameof(args));
}

Type guard

static bool IsSupportedFromSqlArgs(Expression e)
    => e is ConstantExpression c && (c.Value is object[] || c.Value is DBNull || c.Value is null);

Prevention

When it happens

Trigger: Calling FromSqlRaw with a parameter object that is neither a plain object[] nor a DbParameter[], or composing a FromSql query in a way that wraps the argument array in another LINQ/Expression node before it reaches the provider.

Common situations: Migrating a relational FromSqlRaw call to Cosmos expecting identical argument flexibility, passing a single scalar where an array is needed, or building the sql parameter list dynamically and ending up with an unexpected expression shape.

Related errors


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

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs:493

                break;
            }

            case ConstantExpression { Value: object[] constantValues }:
            {
                substitutions = new string[constantValues.Length];
                for (var i = 0; i < constantValues.Length; i++)
                {
                    var value = constantValues[i];
                    var typeMapping = typeMappingSource.FindMapping(value.GetType());
                    Check.DebugAssert(typeMapping is not null, "Could not find type mapping for FromSql parameter");
                    substitutions[i] = ((CosmosTypeMapping)typeMapping).GenerateSqlLiteral(value);
                }

                break;
            }

            default:
                throw new ArgumentOutOfRangeException(
                    nameof(fromSqlExpression),
                    fromSqlExpression.Arguments,
                    CosmosStrings.InvalidFromSqlArguments(
                        fromSqlExpression.Arguments.GetType(),
                        fromSqlExpression.Arguments is ConstantExpression constantExpression
                            ? constantExpression.Value?.GetType()
                            : null));
        }

        // ReSharper disable once CoVariantArrayConversion
        // InvariantCulture not needed since substitutions are all strings
        sql = string.Format(sql, substitutions);

        _sqlBuilder.AppendLine("(");

        using (_sqlBuilder.Indent())
        {
            _sqlBuilder.AppendLines(sql);

View on GitHub (pinned to 3a2006ef56)