Workflow UPDATE_RECORD step silently fails to clear a many-to-one relation field to null
Author: jeyfang0110Created Sep 16, 2026Updated Sep 16, 2026
Labelsprio: high
Bug Description
In a workflow's UPDATE_RECORD step, clearing a many-to-one relation field (choosing "No record" in the UI, which produces a join-column value of null in the step's objectRecord) silently does nothing. The step reports status: SUCCESS in the workflow run, but the record's relation value is unchanged in the database — no error, no warning.
Example:
1. A custom object "lead" with a MANY_TO_ONE relation field "owner" -> workspaceMember
(join column: ownerId). A lead belongs to one workspaceMember (the owner).
2. A lead record that currently has owner/ownerId set to a real workspaceMember.
3. A workflow (manual or DATABASE_EVENT trigger on lead.updated) with an UPDATE_RECORD step
meant to unassign the lead:
objectName: "lead"
objectRecord: { ownerId: null }
fieldsToUpdate: ["ownerId"]
objectRecordId: "<lead id>"
4. Run the workflow against the lead record from step 2.
Expected: ownerId becomes null (lead unassigned). Actual: unchanged, step still reports SUCCESS.
The exact same payload sent as a direct GraphQL mutation (updateLead(id: $id, data: { ownerId: null }))
correctly clears the field — isolating the bug to the workflow UPDATE_RECORD execution path
specifically, not record-update logic in general.
Expected behavior
ownerId (or any other many-to-one relation's join column) becomes null, matching what a direct GraphQL mutation with the same payload does.
Technical inputs
- packages/twenty-server/.../workflow-executor/workflow-actions/record-crud/update-record.workflow-action.ts
UpdateRecordWorkflowAction.execute() -> UpdateRecordService.execute()
-> removeUndefinedFromRecord() (packages/twenty-server/.../utils/remove-undefined-from-record.util.ts)
- removeUndefinedFromRecord is named "remove undefined" but guards with `if (!isDefined(value)) continue;`.
isDefined(null) === false (confirmed empirically alongside isDefined(undefined) === false), so an
explicit null is stripped from the record exactly like undefined, before it ever reaches
commonUpdateOneRunner.execute() / the DB layer. No exception is thrown, so the step reports success.
- Fix: distinguish "not provided" from "explicitly null" — e.g. `if (value === undefined) continue;` —
so null can flow through to the relation/join-column formatting logic that already appears designed
to accept it (see formatWorkflowRecordRelationFields).
- Confirmed on Twenty v2.24.1 (self-hosted): reproduced via both a MANUAL-triggered and a
DATABASE_EVENT-triggered workflow, on a custom "lead" object's MANY_TO_ONE "owner" -> workspaceMember
relation field (join column ownerId). Confirmed the identical payload works via a direct GraphQL
mutation, isolating this to the workflow execution path.
Source: twentyhq/twenty