litedb-org/LiteDB · error · InvalidCastException
Value is not a valid BSON data type - Use Mapper.ToDocument
Error message
Value is not a valid BSON data type - Use Mapper.ToDocument for more complex types converts
What it means
Thrown by the BsonValue implicit-conversion constructor when the supplied object is not null and does not match any recognized BSON-compatible type (primitives, string, byte[], ObjectId, Guid, DateTime, IDictionary, IEnumerable, or another BsonValue). The message directs you to use BsonMapper.ToDocument for custom or complex types that need mapping logic. This is an InvalidCastException, not a LiteException.
Source
Thrown at LiteDB/Document/BsonValue.cs:189
this.Type = BsonType.Document;
this.RawValue = dict;
}
else if (enumerable != null)
{
var list = new List<BsonValue>();
foreach (var x in enumerable)
{
list.Add(new BsonValue(x));
}
this.Type = BsonType.Array;
this.RawValue = list;
}
else
{
throw new InvalidCastException("Value is not a valid BSON data type - Use Mapper.ToDocument for more complex types converts");
}
}
}
#endregion
#region Index "this" property
/// <summary>
/// Get/Set a field for document. Fields are case sensitive - Works only when value are document
/// </summary>
public virtual BsonValue this[string name]
{
get => throw new InvalidOperationException("Cannot access non-document type value on " + this.RawValue);
set => throw new InvalidOperationException("Cannot access non-document type value on " + this.RawValue);
}
/// <summary>View on GitHub (pinned to f906a5f850)
Solutions
- Map the object first: `BsonMapper.Global.ToDocument(myObject)` to convert a POCO into a BsonDocument.
- Convert the value to a supported primitive before wrapping (e.g., cast enum to int, serialize JObject to a string or dictionary).
- Register a custom type converter in BsonMapper if you need the type to be natively supported.
Example fix
// before var value = new BsonValue(myCustomerPoco); // after var value = BsonMapper.Global.ToDocument(myCustomerPoco);
Defensive patterns
Strategy: validation
Validate before calling
if (value != null && !IsBsonSupported(value))
value = BsonMapper.Global.ToDocument(value);
static bool IsBsonSupported(object o) =>
o is int || o is long || o is double || o is decimal ||
o is string || o is byte[] || o is ObjectId || o is Guid ||
o is bool || o is DateTime || o is IDictionary ||
o is IList<BsonValue> || o is BsonValue || o is float[]; Type guard
static bool CanWrapAsBsonValue(object value) {
if (value == null) return true;
var t = value.GetType();
return t.IsPrimitive || t == typeof(string) || t == typeof(decimal) ||
t == typeof(byte[]) || t == typeof(DateTime) || t == typeof(Guid) ||
t == typeof(ObjectId) || t == typeof(float[]) ||
value is IDictionary || value is IList<BsonValue> || value is BsonValue;
} Try / catch
BsonValue bv;
try { bv = new BsonValue(obj); }
catch (InvalidCastException) { bv = BsonMapper.Global.ToDocument(obj); } Prevention
- Always map POCOs through BsonMapper.ToDocument before assigning to BsonValue.
- Register custom type handlers in BsonMapper for domain-specific types.
- Cast enums and nullable types to their BSON-compatible underlying representation explicitly.
When it happens
Trigger: Wrapping a custom POCO, struct, tuple, enum, or any type not on the supported list in a `new BsonValue(myObject)` or assigning it where an implicit BsonValue conversion is expected.
Common situations: Passing a domain model object, a JObject/JToken, a tuple, or an enum directly into a BsonValue or BsonDocument field. Assigning a complex nested object without first mapping it through BsonMapper. Mixing JSON libraries (System.Text.Json / Newtonsoft) and feeding their DOM types into LiteDB.
Related errors
AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13).
Data as JSON: /api/errors/c95e9125b704ac43.
Report an issue: GitHub.