Summary
A field that declares defaultValue and required: true renders in the create dialog with no value selected and a required marker, so the user is forced to pick something the system already knows. The default is served to the console; the create form just does not apply it.
Measured 2026-08-04, @objectstack/console shipped with 17.0.0-rc.1, zh-CN console, fresh database, object create dialog from an object list page.
Repro
Field declaration:
status: Field.select({
label: 'Status',
required: true,
defaultValue: 'draft',
options: [
{ label: 'Draft', value: 'draft', default: true },
{ label: 'Pending Approval', value: 'pending' },
{ label: 'Approved', value: 'approved' },
{ label: 'Rejected', value: 'rejected' },
],
}),
Note both spellings are present — the option's default: true and the field's defaultValue.
The default reaches the console intact. GET /api/v1/meta/objects/crm_customer_rating:
"status": {
"label": "Status", "type": "select", "required": true,
"defaultValue": "draft",
"options": [{ "label": "Draft", "value": "draft", "default": true }, "..."]
}
Expected: the create dialog opens with Draft preselected.
Actual: the select shows its placeholder (请选择 / Select…) with a required asterisk. Nothing is preselected; the form cannot be submitted until the user opens the dropdown and picks a value by hand.
The server side is fine — a create that omits the field entirely is accepted and stored as draft:
$ curl --noproxy '*' -b cookies.txt -H 'Origin: http://localhost:4001' \
-X POST http://localhost:4001/api/v1/data/crm_customer_rating \
-H 'Content-Type: application/json' \
-d '{"crm_account":"...","rating_year":2026}'
{"record":{"...":"...","status":"draft"}}
So this is purely the create form not seeding its default values from the object schema.
Why it matters beyond ergonomics
For a status-like field the forced choice is not neutral — every option is one click away and some of them have side effects. In our app choosing Approved at creation time immediately publishes a grade onto the parent customer record from a scorecard with no facts entered yet. The safe value is the declared default; the UI just refuses to use it.
More generally: defaultValue + required is a normal, correct way to model "this has a sensible starting value". Right now that combination produces the worst create-form experience of any modelling choice — strictly worse than declaring no default at all.
Note
There is code in plugin-form-*.js that builds default values from the object schema —
Object.keys(l.fields).forEach(t => {
let n = l.fields[t];
n.defaultValue !== void 0 && (e[t] = n.defaultValue);
});
— but the object create dialog does not appear to go through it. If that is a component-wiring gap rather than a missing feature, it may be a small fix.
Workaround we shipped
We removed the field from the create form entirely (via a visibleWhen predicate keyed on the record's autonumber being empty) and let the server apply the default. That works, but it is a workaround for the form not honouring metadata it already has — and it only works because conditional visibility happens to be usable here; see #5149 for the ways it is not.
Summary
A field that declares
defaultValueandrequired: truerenders in the create dialog with no value selected and a required marker, so the user is forced to pick something the system already knows. The default is served to the console; the create form just does not apply it.Measured 2026-08-04,
@objectstack/consoleshipped with17.0.0-rc.1, zh-CN console, fresh database, object create dialog from an object list page.Repro
Field declaration:
Note both spellings are present — the option's
default: trueand the field'sdefaultValue.The default reaches the console intact.
GET /api/v1/meta/objects/crm_customer_rating:Expected: the create dialog opens with
Draftpreselected.Actual: the select shows its placeholder (
请选择/Select…) with a required asterisk. Nothing is preselected; the form cannot be submitted until the user opens the dropdown and picks a value by hand.The server side is fine — a create that omits the field entirely is accepted and stored as
draft:So this is purely the create form not seeding its default values from the object schema.
Why it matters beyond ergonomics
For a status-like field the forced choice is not neutral — every option is one click away and some of them have side effects. In our app choosing
Approvedat creation time immediately publishes a grade onto the parent customer record from a scorecard with no facts entered yet. The safe value is the declared default; the UI just refuses to use it.More generally:
defaultValue+requiredis a normal, correct way to model "this has a sensible starting value". Right now that combination produces the worst create-form experience of any modelling choice — strictly worse than declaring no default at all.Note
There is code in
plugin-form-*.jsthat builds default values from the object schema —— but the object create dialog does not appear to go through it. If that is a component-wiring gap rather than a missing feature, it may be a small fix.
Workaround we shipped
We removed the field from the create form entirely (via a
visibleWhenpredicate keyed on the record's autonumber being empty) and let the server apply the default. That works, but it is a workaround for the form not honouring metadata it already has — and it only works because conditional visibility happens to be usable here; see #5149 for the ways it is not.