{"record":{"id":"66aa7630436a809a","repo":"twentyhq/twenty","slug":"failed-to-persist-relation-join-column-index-metad","errorCode":null,"errorMessage":"Failed to persist relation join column index metadata for workspace ${workspaceId}","messagePattern":"Failed to persist relation join column index metadata for workspace (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts","lineNumber":220,"sourceCode":"              flatEntityToCreate: flatIndexBuildPlans.map(\n                ({ universalFlatIndexMetadata }) => universalFlatIndexMetadata,\n              ),\n              flatEntityToDelete: [],\n              flatEntityToUpdate: [],\n            },\n          },\n          workspaceId,\n          applicationUniversalIdentifier:\n            twentyStandardFlatApplication.universalIdentifier,\n        },\n      );\n\n    if (validateAndBuildResult.status === 'fail') {\n      this.logger.error(\n        `Failed to persist relation join column index metadata:\\n${JSON.stringify(validateAndBuildResult, null, 2)}`,\n      );\n\n      throw new Error(\n        `Failed to persist relation join column index metadata for workspace ${workspaceId}`,\n      );\n    }\n\n    this.logger.log(\n      `Successfully backfilled ${flatIndexBuildPlans.length} relation join column index(es) for workspace ${workspaceId}`,\n    );\n  }\n}\n","sourceCodeStart":202,"sourceCodeEnd":230,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts#L202-L230","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Read the logged JSON report to find the failing relation/index and error code.","Reconcile the relation metadata with the actual workspace schema (column exists, types match).","Remove any duplicate/partial index metadata rows for that workspace, then re-run the 2.8 command."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the relation's join column exists in the workspace schema before building index plans:\nfor (const plan of flatIndexBuildPlans) {\n  const cols = await dataSource.query(`SELECT column_name FROM information_schema.columns WHERE table_schema=$1 AND table_name=$2`, [schema, plan.tableName]);\n  if (!cols.some(c => c.column_name === plan.columnName)) { /* reconcile relation metadata first */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await command.runOnWorkspace({ workspaceId, options });\n} catch (e) {\n  logger.error({ workspaceId, err: e.message }, 'relation join column index backfill failed');\n}","preventionTips":["Keep relation metadata consistent with the actual workspace schema (column names/types).","Remove duplicate/partial index metadata rows before retrying.","Avoid out-of-band DB edits to relation join columns."],"tags":["migration","upgrade-command","validate-and-build","workspace","relation","index-metadata","backfill"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}