Summary
The create branch of save() only includes attributes where attr.fillable is true. A value explicitly passed to create({...}) (or set via .set()) for a non-fillable column — the common case for FK columns like user_id — is dropped from the INSERT but kept on the in-memory instance, so the instance disagrees with the DB. On Postgres a NOT-NULL FK with no default then makes the INSERT throw.
Evidence (repro, sqlite)
Post.create({ title:'A', user_id:99 }) // user_id not fillable
-> in-memory user_id = 99 | persisted row = { title:'A', user_id: null }Location
src/orm.ts:~796 (create branch: if (attr.fillable && this._attributes[key] !== undefined)).
Suggested fix
Persist any attribute present in _attributes that maps to a real column (respect guarded, but don't require fillable for values explicitly provided), or at minimum include declared non-fillable attributes that were explicitly set.
Severity: high. Found via internal code audit.