toeverything/AFFiNE · error · Error
[Table(${table.name})]: Field '${key}' type mismatch. Expect
Error message
[Table(${table.name})]: Field '${key}' type mismatch. Expected type '${field.type}' but got '${typeGet}'. What it means
Thrown by the ORM's DataTypeShouldExactlyMatch validator when a value's runtime type (via inputType()) does not match the field's declared t.type(). Only enum fields skip this check (they get error 701 instead). This is a strict, non-coercing type check: '5' will not satisfy a number field.
Source
Thrown at packages/common/infra/src/orm/core/validators/data.ts:120
if (val === undefined || val === null) {
if (!field.optional) {
throw new Error(
`[Table(${table.name})]: Field '${key}' is required but not set.`
);
}
continue;
}
const typeGet = inputType(val);
if (field.type === 'enum') {
if (!field.values?.includes(val)) {
throw new Error(
`[Table(${table.name})]: Field '${key}' value '${val}' is not valid. Expected one of [${field.values?.join(', ')}].`
);
}
} else if (!typeMatches(field.type, typeGet)) {
throw new Error(
`[Table(${table.name})]: Field '${key}' type mismatch. Expected type '${field.type}' but got '${typeGet}'.`
);
}
keys.add(key);
} else if (!table.isDocumentTable) {
// strict check field existence for normal table
throw new Error(
`[Table(${table.name})]: Field '${key}' is not defined but set in entity.`
);
}
}
for (const key in table.schema) {
if (!keys.has(key) && table.schema[key].optional === false) {
throw new Error(
`[Table(${table.name})]: Field '${key}' is required but not set.`
);View on GitHub (pinned to b4c8548c09)
Solutions
- Coerce the value to the declared type before insert: Number(x) for number fields, String(x) or template literals for string fields.
- Fix the schema if the runtime type is actually correct and the declaration is stale (e.g. the column now stores structured data → switch to t.json-compatible type).
- Add a TypeScript type on the create payload (the table's inferred types) so the compiler catches this before runtime.
- Check nested values: a single wrong property inside an object field reported by key still points at the exact field name in the message.
Example fix
// before
await db.doc.create({ id, title: 123 }); // title is t.string()
// after
await db.doc.create({ id, title: String(123) });
// better: type the payload from the table so tsc complains first Defensive patterns
Strategy: type-guard
Validate before calling
function matchesDeclaredType(type: string, v: unknown): boolean {
switch (type) {
case 'string': return typeof v === 'string';
case 'number': return typeof v === 'number' && Number.isFinite(v);
case 'boolean': return typeof v === 'boolean';
default: return true; // json/other: assume valid, let server/validator decide
}
} Type guard
const isStr = (v: unknown): v is string => typeof v === 'string'; const isNum = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v); const isBool = (v: unknown): v is boolean => typeof v === 'boolean';
Try / catch
try { await db.doc.create(payload); } catch (e) { if (e instanceof Error && e.message.includes('type mismatch')) { /* coerce the named field and retry once */ } throw e; } Prevention
- Coerce URL/localStorage/form values before insert (Number(), String())
- Let TypeScript infer payload types from the table schema
- Watch out for JSON round-trips turning numbers into strings
When it happens
Trigger: Passing '5' (string) to t.number(), 5 (number) to t.string(), an array/object to a scalar field, or a boolean where the schema says 'string'. Also fires for JSON-typed fields when inputType()'s classification of the value differs from the declared type.
Common situations: Values coming from URL query params, localStorage, or GraphQL variables that are always strings; form inputs that yield strings for numeric fields; JSON.parse'd payloads where a number was serialized as string; switching a field type in the schema without updating the code that writes it.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Validation Failed Error\n${message}
- ValueNotExists
- Param not a number: ${mode},${numbeToken.text}
- A curve must have at least three points.
- Invalid config for module [${module}] with key [${key}] Valu
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/a07b6d7d770242ab.
Report an issue: GitHub.