Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 5640fc1a7b fix: gracefully handle missing relation target object in entity schema builder
https://sonarly.com/issue/19870?type=bug

A workspace has a field metadata record with `relationTargetObjectMetadataId` pointing to a non-existent object, causing the ORM entity schema cache build to throw during workflow execution on the worker.
2026-03-31 07:10:18 +00:00
@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
@@ -22,6 +22,8 @@ type RelationFieldMetadata = EntitySchemaFieldMetadata<
@Injectable()
export class EntitySchemaRelationFactory {
private readonly logger = new Logger(EntitySchemaRelationFactory.name);
constructor() {}
create(
@@ -40,6 +42,22 @@ export class EntitySchemaRelationFactory {
continue;
}
// Parallel queries without a shared transaction can observe different
// snapshots under READ COMMITTED isolation. A concurrent ObjectMetadata
// hard-delete (with FK CASCADE on FieldMetadata) that commits between
// the ObjectMetadata and FieldMetadata queries leaves orphaned relation
// fields in the result set. Skip them to avoid failing the entire cache.
if (
!fieldMetadata.relationTargetObjectMetadataId ||
!objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId]
) {
this.logger.warn(
`Skipping orphaned relation field ${fieldMetadata.id}: target ObjectMetadata ${fieldMetadata.relationTargetObjectMetadataId ?? 'null'} not found`,
);
continue;
}
const relationDetails = determineSchemaRelationDetails(
fieldMetadata,
objectMetadataMaps,