You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] ImportRequest.runAutomations declares .default(false) and documents "off by default for bulk", but POST /data/:object/import defaults it ON #6704
Observation-class finding, recorded while documenting the import dry-run hook boundary (#6537, PR for it links back here). Not fixed there: the fix is a contract call, not a docs edit.
What was measured
packages/spec/src/api/export.zod.ts (ImportRequestSchema, the body schema of POST /api/v1/data/:object/import and of CreateImportJobRequest):
runAutomations: z.boolean().default(false).describe('Fire triggers/hooks for each imported row (off by default for bulk)'),
packages/rest/src/import-prepare.ts:262, the code that actually decides:
// Default ON: automations always ran historically (the engine ignored the// flag until #2922), so opt-out must be explicit — matches platform// convention (Salesforce runs triggers on import by default).construnAutomations=body?.runAutomations!==false;
So an omitted runAutomations runs automations. The declared default and the prose next to it both say the opposite, and both ship: the describe text renders into the published reference page (content/docs/references/api/export.mdx, ImportRequest + CreateImportJobRequest tables), and .default(false) ships in @objectstack/spec's JSON Schema.
Why it is not merely cosmetic
The route never parses its body through ImportRequestSchema — prepareImport reads the raw body — so nothing reconciles the two today. The divergence bites in two directions:
A client or SDK that does parse the request through the schema materializes runAutomations: false from the declared default and sends it explicitly. The server then honours it: automations off, silently, for a caller who set nothing. Same request body in, opposite behaviour, decided by whether the caller validated it.
An author reading the reference page is told bulk import does not fire triggers by default. It does.
This is the declared-versus-enforced shape of Prime Directive #10, on a flag that decides whether user-authored hooks run over a whole spreadsheet.
Dispositions (a contract call — deliberately not guessed here)
A. Move the spec to the runtime: .default(true) plus corrected prose. Zero runtime change, but it flips the declared default of a shipped published schema, so it needs a version/level decision and possibly a note for parsing clients.
C. Keep both and remove the ambiguity: drop .default() (leave it optional with no declared default) and state the server-side default in the describe text, so the schema stops asserting a default it does not own.
No recommendation is offered without the maintainer's read on who is allowed to parse this schema — that is the fact that decides between A and C.
That PR documents the dry-run boundary on ImportRequest.dryRun and deliberately phrases it as "a dry run with runAutomations: true" rather than naming a default, precisely so it does not have to take a side here.
Observation-class finding, recorded while documenting the import dry-run hook boundary (#6537, PR for it links back here). Not fixed there: the fix is a contract call, not a docs edit.
What was measured
packages/spec/src/api/export.zod.ts(ImportRequestSchema, the body schema ofPOST /api/v1/data/:object/importand ofCreateImportJobRequest):packages/rest/src/import-prepare.ts:262, the code that actually decides:So an omitted
runAutomationsruns automations. The declared default and the prose next to it both say the opposite, and both ship: the describe text renders into the published reference page (content/docs/references/api/export.mdx, ImportRequest + CreateImportJobRequest tables), and.default(false)ships in@objectstack/spec's JSON Schema.Why it is not merely cosmetic
The route never parses its body through
ImportRequestSchema—prepareImportreads the raw body — so nothing reconciles the two today. The divergence bites in two directions:runAutomations: falsefrom the declared default and sends it explicitly. The server then honours it: automations off, silently, for a caller who set nothing. Same request body in, opposite behaviour, decided by whether the caller validated it.This is the declared-versus-enforced shape of Prime Directive #10, on a flag that decides whether user-authored hooks run over a whole spreadsheet.
Dispositions (a contract call — deliberately not guessed here)
.default(true)plus corrected prose. Zero runtime change, but it flips the declared default of a shipped published schema, so it needs a version/level decision and possibly a note for parsing clients.body?.runAutomations === true. A real behaviour change on a documented-since-数据导入:批量 insert 给 Hook 的输入形状与单条不一致(installFlatInput 失效);「运行自动化与触发器」开关是摆设且默认值应为选中 #2922 default, and it contradicts the reasoning recorded in theimport-prepare.tscomment above; almost certainly wrong, listed for completeness..default()(leave it optional with no declared default) and state the server-side default in the describe text, so the schema stops asserting a default it does not own.No recommendation is offered without the maintainer's read on who is allowed to parse this schema — that is the fact that decides between A and C.
Not touched by #6537's PR
That PR documents the dry-run boundary on
ImportRequest.dryRunand deliberately phrases it as "a dry run withrunAutomations: true" rather than naming a default, precisely so it does not have to take a side here.