litedb-org/LiteDB · error · LiteException

ENTITY_INITIALIZATION_FAILED

ENTITY_INITIALIZATION_FAILED

Error message

Initialization timeout

What it means

Thrown by EntityMapper.WaitForInitialization when the CancellationToken WaitHandle is not signalled within 5 seconds. The token comes from GetEntityMapper, which creates a CancellationTokenSource, builds the EntityMapper via BuildEntityMapper, then cancels the token in its finally block. A timeout means BuildEntityMapper took longer than 5 seconds, indicating the entity build is stuck or extremely slow.

Source

Thrown at LiteDB/Client/Mapper/EntityMapper.cs:67

        {
            return this.Members.FirstOrDefault(x => x.MemberName == expr.GetPath());
        }

        public void WaitForInitialization()
        {
            if
            (
                _initializationToken == default
                || _initializationToken == CancellationToken.None
                || _initializationToken.IsCancellationRequested
            )
            {
                return;
            }

            if (!_initializationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)))
            {
                throw new LiteException(LiteException.ENTITY_INITIALIZATION_FAILED, "Initialization timeout");
            }
        }
    }
}

View on GitHub (pinned to f906a5f850)

Solutions

  1. Inspect custom ResolveMember, ResolveFieldName, ResolveCollectionName, and ResolveTypeName callbacks for slow or blocking operations and make them synchronous and fast.
  2. Pre-warm the mapper at application startup by calling mapper.GetEntityMapper(typeof(T)) for each entity type before concurrent queries hit it.
  3. Simplify complex or self-referencing entity graphs and break circular DbRef chains.
  4. If using a custom BsonMapper subclass, ensure BuildEntityMapper/GetTypeMembers overrides do not call back into GetEntityMapper in a way that could deadlock.

Example fix

// before -- custom resolver does slow work
mapper.ResolveMember = (type, memberInfo, memberMapper) =>
{
    memberMapper.FieldName = LoadAliasFromDatabase(memberInfo.Name); // blocking I/O
};

// after -- cache aliases up front
var aliases = LoadAllAliases(); // at startup
mapper.ResolveMember = (type, memberInfo, memberMapper) =>
{
    if (aliases.TryGetValue(memberInfo.Name, out var alias))
        memberMapper.FieldName = alias;
};
Defensive patterns

Strategy: validation

Validate before calling

// Pre-warm all entity types at startup to avoid initialization under load
foreach (var entityType in new[] { typeof(User), typeof(Order), typeof(Product) })
{
    mapper.GetEntityMapper(entityType);
}

Try / catch

try
{
    mapper.GetEntityMapper(typeof(T));
}
catch (LiteException ex) when (ex.ErrorCode == LiteException.ENTITY_INITIALIZATION_FAILED)
{
    logger.LogError(ex, "Entity mapping initialization timed out for {Type}", typeof(T).Name);
    throw;
}

Prevention

When it happens

Trigger: Any code path that calls WaitForInitialization (EntityBuilder.GetMember, LinqExpressionVisitor.ResolveMember, or direct calls) while GetEntityMapper is still executing BuildEntityMapper for the same or a related type and that build has not completed within the 5-second window.

Common situations: A custom BsonMapper.ResolveMember callback that performs slow or blocking work (network, disk, heavy computation). A deeply recursive or circular entity graph that causes GetEntityMapper to call itself in a way that stalls. Heavy resource contention on first use under load without pre-warming the mapper. A deadlock between threads if a custom resolver callback re-enters the mapper on the same type from a different thread.

Understand the failure class

Related errors


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