twentyhq/twenty · error · Error

Failed to persist relation join column index metadata for wo

Error message

Failed to persist relation join column index metadata for workspace ${workspaceId}

What it means

Thrown by the 2.8 command that backfills relation join-column index metadata. It computes flatIndexBuildPlans and submits them via validateBuildAndRunLegacyWorkspaceMigration; on status === 'fail' it logs the report and throws. The report identifies which relation/index flat entity failed validation.

Source

Thrown at packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts:220

              flatEntityToCreate: flatIndexBuildPlans.map(
                ({ universalFlatIndexMetadata }) => universalFlatIndexMetadata,
              ),
              flatEntityToDelete: [],
              flatEntityToUpdate: [],
            },
          },
          workspaceId,
          applicationUniversalIdentifier:
            twentyStandardFlatApplication.universalIdentifier,
        },
      );

    if (validateAndBuildResult.status === 'fail') {
      this.logger.error(
        `Failed to persist relation join column index metadata:\n${JSON.stringify(validateAndBuildResult, null, 2)}`,
      );

      throw new Error(
        `Failed to persist relation join column index metadata for workspace ${workspaceId}`,
      );
    }

    this.logger.log(
      `Successfully backfilled ${flatIndexBuildPlans.length} relation join column index(es) for workspace ${workspaceId}`,
    );
  }
}

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Read the logged JSON report to find the failing relation/index and error code.
  2. Reconcile the relation metadata with the actual workspace schema (column exists, types match).
  3. Remove any duplicate/partial index metadata rows for that workspace, then re-run the 2.8 command.
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the relation's join column exists in the workspace schema before building index plans:
for (const plan of flatIndexBuildPlans) {
  const cols = await dataSource.query(`SELECT column_name FROM information_schema.columns WHERE table_schema=$1 AND table_name=$2`, [schema, plan.tableName]);
  if (!cols.some(c => c.column_name === plan.columnName)) { /* reconcile relation metadata first */ }
}

Try / catch

try {
  await command.runOnWorkspace({ workspaceId, options });
} catch (e) {
  logger.error({ workspaceId, err: e.message }, 'relation join column index backfill failed');
}

Prevention

When it happens

Trigger: A relation whose join column the index targets no longer exists or was renamed; the index metadata references a column absent from the workspace schema; a duplicate index definition collides with an existing one; the relation metadata is inconsistent with the actual DB schema (column/type mismatch).

Common situations: Workspaces with manually altered relations; cross-version upgrade where a relation was renamed in an intermediate release; schema drift between core metadata and the workspace schema after out-of-band DB edits; prior partial run that created some index metadata.

Related errors


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