Why do SurrealDB updates fail after I add a field with a TYPE?
DEFINE FIELD with a required type on an existing table
Critical: SurrealDB refuses the migration, loses data, or leaks a credential.
What happens
Observed on SurrealDB 3.0.2: CREATE customer:1, then DEFINE FIELD region ON customer TYPE string succeeds, and the next UPDATE customer:1 SET name = 'b' fails with "Couldn't coerce value for field `region` of `customer:1`: Expected `string` but found `NONE`". The same happens with DEFAULT 'eu'; DEFAULT ALWAYS, VALUE, option<string> and string | none all let the update through.
Why it is dangerous on a populated table
SurrealDB checks a schema change against new writes, not the records already stored, so an empty table hides it: on a populated one every old record is a write waiting to fail, and whole-table work runs for the length of the table in one transaction.
Fires on
DEFINE FIELD region ON TABLE customer TYPE string;The safe pattern
Make the field optional (option<T>) until every record carries it, give it DEFAULT ALWAYS so SurrealDB fills it on every write, or backfill it in the same migration.
DEFINE FIELD region ON TABLE customer TYPE string DEFAULT ALWAYS 'eu';Fixtures
The rule ships with these files and the test suite runs them on every change: the first set must fire, the second must stay silent.
Fires (3)
DEFINE FIELD IF NOT EXISTS loyalty_points ON customer TYPE int;-- DEFAULT only fills the field on CREATE; existing records still lack it.
DEFINE FIELD region ON TABLE customer TYPE string DEFAULT 'eu';DEFINE FIELD region ON TABLE customer TYPE string;Stays silent (7)
DEFINE FIELD region ON TABLE customer TYPE string;
UPDATE customer SET region = 'eu' WHERE region IS NONE;DEFINE FIELD updated_at ON TABLE customer TYPE datetime VALUE time::now();DEFINE FIELD region ON TABLE customer TYPE string DEFAULT ALWAYS 'eu';DEFINE FIELD address.city ON TABLE customer TYPE string;DEFINE TABLE customer SCHEMAFULL;
DEFINE FIELD region ON TABLE customer TYPE string;DEFINE FIELD region ON TABLE customer TYPE option<string>;DEFINE FIELD region ON TABLE customer TYPE string | none;How to check locally
SurrealDB support is in beta: this rule runs locally in the free CLI over .surql migrations, static only, and not in the hosted service yet. No install, nothing leaves your machine:
npx bolvrk check migration.surql --engine=surrealdb