twentyhq/twenty · critical · WorkspaceMigrationBuilderException
Multiple validation errors occurred while normalizing compos
Error message
Multiple validation errors occurred while normalizing composite field defaults
What it means
Thrown by the 2.5 command that normalizes composite field default values (replaces empty-string composite defaults with NULL). Unlike the others, it throws a WorkspaceMigrationBuilderException carrying the failed result and this message. It groups affected composite fields by application and submits each batch through validateBuildAndRunLegacyWorkspaceMigration (isSystemBuild: true); the first batch whose status === 'fail' raises the exception. The exception's failedWorkspaceMigrationBuildResult.report details the failing field(s).
Source
Thrown at packages/twenty-server/src/database/commands/upgrade-version-command/2-5/2-5-workspace-command-1778000001000-normalize-composite-field-defaults.command.ts:190
const validateAndBuildResult =
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunLegacyWorkspaceMigration(
{
allFlatEntityOperationByMetadataName: {
fieldMetadata: {
flatEntityToCreate: [],
flatEntityToDelete: [],
flatEntityToUpdate: flatFieldMetadatasToUpdate,
},
},
workspaceId,
isSystemBuild: true,
applicationUniversalIdentifier,
},
);
if (validateAndBuildResult.status === 'fail') {
throw new WorkspaceMigrationBuilderException(
validateAndBuildResult,
'Multiple validation errors occurred while normalizing composite field defaults',
);
}
for (const field of fields) {
this.logger.log(
`Normalized defaultValue for composite field "${field.name}" (${field.id}) in workspace ${workspaceId}`,
);
}
}
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
'flatFieldMetadataMaps',
]);
for (const { tableName, columnName } of backfillTargets) {
await dataSource.query(View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Catch WorkspaceMigrationBuilderException and read exception.failedWorkspaceMigrationBuildResult.report — it lists the failing field universalIdentifier(s) and error codes.
- For each flagged field, inspect its stored defaultValue JSON and correct it to match the composite type definition (or set it to NULL).
- Re-run the 2.5 command for the workspace; the field will be skipped once its default is valid.
Defensive patterns
Strategy: try-catch
Validate before calling
// Per composite field, validate the normalized shape before submitting:
const normalized = nullifyEmptyCompositeDefaultValue({ defaultValue: field.defaultValue, fieldType: field.type });
for (const property of compositeType.properties) {
if (normalized && !(property.name in normalized)) { /* repair field.defaultValue first */ }
} Try / catch
try {
await command.runOnWorkspace({ workspaceId, options });
} catch (e) {
if (e instanceof WorkspaceMigrationBuilderException) {
const report = e.failedWorkspaceMigrationBuildResult.report;
logger.error({ workspaceId, report }, 'composite default normalize failed');
} else throw e;
} Prevention
- Avoid setting non-standard defaultValue shapes on composite fields in app code.
- On failure, read exception.failedWorkspaceMigrationBuildResult.report to find the offending field.
- Set a malformed field's defaultValue to NULL before retrying.
When it happens
Trigger: A composite field's normalized defaultValue shape fails the field-metadata validator (unknown property, wrong type per composite type definition); the field references an object that no longer exists; a compositeTypeDefinitions entry for the field's type is malformed so nullifyEmptyCompositeDefaultValue produced an invalid shape.
Common situations: Workspaces with custom composite fields whose defaultValue was set to non-standard shapes by older app code; cross-version upgrade where the composite type definition changed between releases; manual DB edits that left empty strings in composite default JSON.
Related errors
- Failed to add NOT_RECORDED to CallRecording status metadata
- Failed to backfill standard skills for workspace ${workspace
- Failed to create the workspaceMember openRecordIn field for
- Failed to seed object openRecordIn for workspace ${workspace
- Failed to sync "Discard Draft" workflow command menu item av
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/51311199b395e165.
Report an issue: GitHub.