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

  1. Read the logger.error JSON to find the failing entity and error code.
  2. Inspect core.fieldMetadata and the view/viewField tables for existing messageCampaign stat rows that conflict; remove or reconcile.
  3. Confirm the messageCampaign object exists and matches the standard seed.
  4. 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

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


AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12). Data as JSON: /api/errors/2ba0527a20199e4d. Report an issue: GitHub.