lancedb/lancedb · error · Error
Expected a Union type to have an array-like `children`…
Error message
Expected a Union type to have an array-like `children` property
What it means
LanceDB's TypeScript sanitizer rebuilds Arrow schema types from plain serialized objects. When sanitizing a Union type, it requires the input object to have a `children` property that is an actual Array. This error is thrown when the property is missing or is not array-like, so the Union cannot be reconstructed with its child fields.
Solutions
- Add an array `children` property containing the union's child Field objects.
- Verify each entry of `children` is a serializable Field object the sanitizer can process.
- Re-generate the schema from a real Arrow table/schema rather than hand-editing JSON.
- Catch the error and log the offending type object to identify which union is malformed.
Example fix
// before
sanitizeTypeById(9, { mode: 0 });
// after
sanitizeTypeById(9, { mode: 0, children: [
new Field('int', new Int32(), true),
new Field('str', new Utf8(), true),
] }); Defensive patterns
Strategy: type-guard
Validate before calling
function assertUnionLike(t) {
if (!t || !Array.isArray(t.children)) {
throw new Error('Union type object must have an array `children` property');
}
return t;
}
assertUnionLike(typeLike); // call before sanitizeTypeById Type guard
function isUnionLike(t) {
return typeof t === 'object' && t !== null && Array.isArray(t.children);
} Try / catch
try {
const union = sanitizeUnion(typeLike, context);
} catch (e) {
if (String(e.message).includes('array-like `children`')) {
console.error('Malformed union type object:', JSON.stringify(typeLike));
} else { throw e; }
} Prevention
- Always serialize schemas from real Arrow objects rather than writing JSON by hand.
- Add a schema-shape validator that runs before sanitization in your pipeline.
- Pin the LanceDB version so serialization formats do not drift unexpectedly.
- Unit-test schema round-trips (type -> serialize -> sanitize) for union fields.
When it happens
Trigger: Calling sanitizeTypeById (directly or via sanitizeUnion) on an object with an Arrow Union TypeCode whose `children` is absent, null, or not an Array — e.g. a hand-written or truncated JSON schema object like {mode: 0} with no children, or children set to a non-array value.
Common situations: Hand-authoring serialized schemas instead of round-tripping real Arrow types; an older client serializing union types without children; a migration/version change where the union serialization format dropped `children`; copy-paste errors omitting nested fields in a schema JSON file.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Expected a DenseUnion/SparseUnion type to have a `typeIds`…
- Expected a DenseUnion/SparseUnion type to have an…
- Expected a Union type to have `typeIds` and `mode`…
- At least one record or a schema needs to be provided
- Expected a Date type to have a `unit` property
AI-assisted analysis of lancedb/lancedb@c7b051aff7 (2026-09-08).
Data as JSON: /api/errors/bea07079d6925517.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/lancedb/sanitize.ts:264
export function sanitizeUnion(typeLike: object) {
return sanitizeUnionWithContext(typeLike, createSanitizationContext());
}
function sanitizeUnionWithContext(
typeLike: object,
context: SanitizationContext,
) {
if (
!("typeIds" in typeLike) ||
!("mode" in typeLike) ||
typeof typeLike.mode !== "number"
) {
throw Error(
"Expected a Union type to have `typeIds` and `mode` properties",
);
}
if (!("children" in typeLike) || !Array.isArray(typeLike.children)) {
throw Error(
"Expected a Union type to have an array-like `children` property",
);
}
return new Union(
typeLike.mode,
// biome-ignore lint/suspicious/noExplicitAny: skip
typeLike.typeIds as any,
typeLike.children.map((child) => sanitizeFieldWithContext(child, context)),
);
}
export function sanitizeTypedUnion(
typeLike: object,
// eslint-disable-next-line @typescript-eslint/naming-convention
UnionType: typeof DenseUnion | typeof SparseUnion,
) {
return sanitizeTypedUnionWithContext(View on GitHub (pinned to c7b051aff7)