litedb-org/LiteDB · error · NotSupportedException

New instance are not supported for {node.Type} when convert

Error message

New instance are not supported for {node.Type} when convert to BsonExpression ({node.ToString()}).

What it means

Thrown by VisitNew when a new SomeType(args) expression is encountered where SomeType has NO registered resolver and node.Members is null (meaning it is a plain constructor call, not a member-init anonymous-type projection). LiteDB cannot construct arbitrary types via parameterized constructors in BsonExpression translation.

Source

Thrown at LiteDB/Client/Mapper/Linq/LinqExpressionVisitor.cs:366

        /// <summary>
        /// Visit :: x => `new { x.Id, x.Name }`
        /// </summary>
        protected override Expression VisitNew(NewExpression node)
        {
            if (node.Members == null)
            {
                if (TryGetResolver(node.Type, out var type))
                {
                    var pattern = type.ResolveCtor(node.Constructor);

                    if (pattern == null) throw new NotSupportedException($"Constructor for {node.Type.Name} are not supported when convert to BsonExpression ({node.ToString()}).");

                    this.ResolvePattern(pattern, null, node.Arguments);
                }
                else
                {
                    throw new NotSupportedException($"New instance are not supported for {node.Type} when convert to BsonExpression ({node.ToString()}).");
                }
            }
            else
            {
                _builder.Append("{ ");

                for (var i = 0; i < node.Members.Count; i++)
                {
                    var member = node.Members[i];
                    _builder.Append(i > 0 ? ", " : "");
                    _builder.AppendFormat("'{0}': ", member.Name);
                    this.Visit(node.Arguments[i]);
                }

                _builder.Append(" }");
            }

            return node;

View on GitHub (pinned to f906a5f850)

Solutions

  1. Use member-initializer syntax (new MyDto { Id = x.Id, Name = x.Name }) instead of a parameterized constructor, provided the type has a parameterless ctor.
  2. Hoist the construction out of the expression and fetch-then-project in memory.
  3. Register a custom ITypeResolver with a ResolveCtor pattern if translation is required.

Example fix

// before -- parameterized ctor in query
var dtos = col.Find(x => x.Value > new Threshold(10).Limit);

// after -- hoist the constant
var limit = new Threshold(10).Limit;
var dtos = col.Find(x => x.Value > limit);
Defensive patterns

Strategy: validation

Validate before calling

// Avoid new CustomType(args) in query expressions; use member-initializers or hoist
var limit = new Threshold(10).Limit; // evaluate outside
col.Find(x => x.Value > limit);

Try / catch

try
{
    var results = col.Find(x => x.Value > new Threshold(10).Limit);
}
catch (NotSupportedException ex) when (ex.Message.Contains("New instance are not supported for"))
{
    var limit = new Threshold(10).Limit;
    results = col.Find(x => x.Value > limit);
}

Prevention

When it happens

Trigger: Using new with a user-defined type that has constructor parameters inside a LINQ query. For example x => new MyDto(x.Id, x.Name) in a projection or predicate, where MyDto has no ITypeResolver.

Common situations: Projecting query results into DTOs or value objects with parameterized constructors inside the LINQ expression itself. Using value objects or records with primary constructors in query predicates.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/853cc2ded663d259. Report an issue: GitHub.