twenty
twenty copied to clipboard
Workflows' nodes input schema is wrong, showing unfetched fields
Bug Description
Workflow editor reports unavailable keys as available and hides available fields for relation fields.
Example:
Custom object "Appointment" with relation with workspace member and person (client). In workflow editor, when selecting node's inputs, I can select all fields from the workspace member and person records.
However only the fields memberid and personid are displayed in workflow run.
The node don't fetch them when selecting member > id or person > id as input because the field is memberid not member.id
It means workflow will not work as intended, using a blank string instead of record's data.
Expected behavior
Workflow editor's proposed fields should be usable. Either the linked objects' fields are all available for the workflow, or the linked object id is displayed without depth in the node's input selector.
Technical inputs
Version 1.10.1 - self-host (great version btw, love the UI and UX improvements)
Additional input
Trigger nodes Record is updated, Record is created and Record is created or updated triggers have different data fetching depth:
Record is updatedfetches the whole related object's recordRecord is updated or createdfetches only the related object's id Yet, in node's input fields, all related object's fields can be selected, despite being not fetched.
For the missing data in trigger, I potentially found the root cause here: packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/workflow-database-event-trigger.listener.ts
Lines 66 - 82
@OnDatabaseBatchEvent('*', DatabaseEventAction.UPDATED)
async handleObjectRecordUpdateEvent(
payload: WorkspaceEventBatch<ObjectRecordUpdateEvent>,
) {
if (await this.shouldIgnoreEvent(payload)) {
return;
}
const clonedPayload = structuredClone(payload);
await this.enrichUpdatedEvent(clonedPayload);
await this.handleEvent({
payload: clonedPayload,
action: DatabaseEventAction.UPDATED,
});
}
Lines 118 - 132
@OnDatabaseBatchEvent('*', DatabaseEventAction.UPSERTED)
async handleObjectRecordUpsertEvent(
payload: WorkspaceEventBatch<ObjectRecordUpsertEvent>,
) {
if (await this.shouldIgnoreEvent(payload)) {
return;
}
const clonedPayload = structuredClone(payload);
await this.handleEvent({
payload: clonedPayload,
action: DatabaseEventAction.UPSERTED,
});
}
Missing the enrich function.
A potential fix would be to add a function something similar to this:
private async enrichUpsertedEvent(
payload: WorkspaceEventBatch<ObjectRecordUpsertEvent>,
) {
const workspaceId = payload.workspaceId;
const { objectMetadataMaps, objectMetadataItemWithFieldsMaps } =
await this.workflowCommonWorkspaceService.getObjectMetadataItemWithFieldsMaps(
payload.objectMetadata.nameSingular,
workspaceId,
);
await this.enrichRecordsWithRelations({
records: payload.events.map((event) => event.properties.before),
workspaceId,
objectMetadataMaps,
objectMetadataItemWithFieldsMaps,
});
await this.enrichRecordsWithRelations({
records: payload.events.map((event) => event.properties.after),
workspaceId,
objectMetadataMaps,
objectMetadataItemWithFieldsMaps,
});
}
And to enrich the handleObjectRecordUpsertEvent function with:
await this.enrichUpsertedEvent(clonedPayload);