{"record":{"id":"2ba0527a20199e4d","repo":"twentyhq/twenty","slug":"failed-to-add-messagecampaign-stat-fields-for-work","errorCode":null,"errorMessage":"Failed to add messageCampaign stat fields for workspace ${workspaceId}","messagePattern":"Failed to add messageCampaign stat fields for workspace (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-workspace-command-1783525261000-add-message-campaign-stat-fields.command.ts","lineNumber":211,"sourceCode":"                flatEntityToCreate: viewsToCreate,\n                flatEntityToDelete: [],\n                flatEntityToUpdate: [],\n              },\n              viewField: {\n                flatEntityToCreate: viewFieldsToCreate,\n                flatEntityToDelete: [],\n                flatEntityToUpdate: [],\n              },\n            },\n          },\n        );\n\n      if (result.status === 'fail') {\n        this.logger.error(\n          `Failed to add messageCampaign stat fields:\\n${JSON.stringify(result, null, 2)}`,\n        );\n\n        throw new Error(\n          `Failed to add messageCampaign stat fields for workspace ${workspaceId}`,\n        );\n      }\n    }\n\n    this.logger.log(\n      `Applied messageCampaign stat fields for workspace ${workspaceId}`,\n    );\n  }\n\n  private resolveViewsToCreate({\n    flatViewMaps,\n    standardAllFlatEntityMaps,\n  }: {\n    flatViewMaps: WorkspaceCacheDataMap['flatViewMaps'];\n    standardAllFlatEntityMaps: TwentyStandardAllFlatEntityMaps;\n  }): FlatView[] {\n    if (","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-workspace-command-1783525261000-add-message-campaign-stat-fields.command.ts#L193-L229","documentation":"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.","triggerScenarios":"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.","commonSituations":"Workspace with custom messageCampaign fields sharing universal identifiers; prior partial run leaving half-created rows; messageCampaign object drifted from standard; concurrent migrations.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm no conflicting messageCampaign stat rows already exist.\nconst existing = await dataSource.query(`\n  SELECT f.\"nameSingular\" FROM core.\"fieldMetadata\" f\n  JOIN core.\"objectMetadata\" o ON o.\"id\" = f.\"objectMetadataId\"\n  WHERE o.\"nameSingular\" = 'messageCampaign'\n    AND f.\"nameSingular\" = ANY($1::text[])\n`, [statFieldNames]);\nif (existing.length) throw new Error('messageCampaign stat rows already present; reconcile before upgrade');","typeGuard":"function isFailResult(r: unknown): r is { status: 'fail' } {\n  return typeof r === 'object' && r !== null && (r as any).status === 'fail';\n}","tryCatchPattern":"try {\n  const res = await service.validateBuildAndRunLegacyWorkspaceMigration(payload);\n  if (res.status === 'fail') throw new Error(`... for workspace ${workspaceId}`);\n} catch (err) { upgradeAudit.record(workspaceId, command.id, err); throw err; }","preventionTips":["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."],"tags":["migration","workspace-upgrade","metadata-validation","message-campaign"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}