twentyhq/twenty · error · Error
Failed to add messageCampaign stat fields for workspace ${wo
Error message
Failed to add messageCampaign stat fields for workspace ${workspaceId} What it means
Thrown by the 2.20 add-message-campaign-stat-fields command when result.status === 'fail' after attempting to create the resolved messageCampaign stat fields, views, and view fields for the workspace. The logger.error above prints the full result. The standard seed checks (134, 135) have passed, so this is a per-workspace build-phase rejection.
Source
Thrown at packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-workspace-command-1783525261000-add-message-campaign-stat-fields.command.ts:211
flatEntityToCreate: viewsToCreate,
flatEntityToDelete: [],
flatEntityToUpdate: [],
},
viewField: {
flatEntityToCreate: viewFieldsToCreate,
flatEntityToDelete: [],
flatEntityToUpdate: [],
},
},
},
);
if (result.status === 'fail') {
this.logger.error(
`Failed to add messageCampaign stat fields:\n${JSON.stringify(result, null, 2)}`,
);
throw new Error(
`Failed to add messageCampaign stat fields for workspace ${workspaceId}`,
);
}
}
this.logger.log(
`Applied messageCampaign stat fields for workspace ${workspaceId}`,
);
}
private resolveViewsToCreate({
flatViewMaps,
standardAllFlatEntityMaps,
}: {
flatViewMaps: WorkspaceCacheDataMap['flatViewMaps'];
standardAllFlatEntityMaps: TwentyStandardAllFlatEntityMaps;
}): FlatView[] {
if (View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Read the logger.error JSON to find the failing entity and error code.
- Inspect core.fieldMetadata and the view/viewField tables for existing messageCampaign stat rows that conflict; remove or reconcile.
- Confirm the messageCampaign object exists and matches the standard seed.
- Re-run the workspace upgrade.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm no conflicting messageCampaign stat rows already exist.
const existing = await dataSource.query(`
SELECT f."nameSingular" FROM core."fieldMetadata" f
JOIN core."objectMetadata" o ON o."id" = f."objectMetadataId"
WHERE o."nameSingular" = 'messageCampaign'
AND f."nameSingular" = ANY($1::text[])
`, [statFieldNames]);
if (existing.length) throw new Error('messageCampaign stat rows already present; reconcile before upgrade'); Type guard
function isFailResult(r: unknown): r is { status: 'fail' } {
return typeof r === 'object' && r !== null && (r as any).status === 'fail';
} Try / catch
try {
const res = await service.validateBuildAndRunLegacyWorkspaceMigration(payload);
if (res.status === 'fail') throw new Error(`... for workspace ${workspaceId}`);
} catch (err) { upgradeAudit.record(workspaceId, command.id, err); throw err; } Prevention
- Detect pre-existing custom fields/views sharing standard universal identifiers before upgrade.
- Clean up half-created rows from prior failed runs.
- Run upgrades with API mutations paused.
When it happens
Trigger: Running the 2.20 upgrade on a workspace where some of the stat fields/view columns already exist in a conflicting state, where the messageCampaign object is missing/inconsistent, or where the create payload fails schema validation.
Common situations: Workspace with custom messageCampaign fields sharing universal identifiers; prior partial run leaving half-created rows; messageCampaign object drifted from standard; concurrent migrations.
Related errors
- Migration failed for workspace ${workspaceId} while healing
- Failed to create CallRecording recordingRequestStatus metada
- Failed to delete CalendarEvent recordingPreference field for
- Failed to create CalendarEvent record page metadata for work
- Failed to persist searchFieldMetadata rows for workspace ${w
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/2ba0527a20199e4d.
Report an issue: GitHub.