{"record":{"id":"65fb0bd08e84e80a","repo":"twentyhq/twenty","slug":"migration-failed-for-workspace-workspaceid-whil","errorCode":null,"errorMessage":"Migration failed for workspace ${workspaceId} while healing standard relation field labels/icons:\\n${failureDetails}","messagePattern":"Migration failed for workspace (.+?) while healing standard relation field labels/icons:\\\\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-server/src/database/commands/upgrade-version-command/2-14/2-14-workspace-command-1799000040000-fix-standard-relation-field-labels-icons.command.ts","lineNumber":157,"sourceCode":"      );\n\n    if (result.status === 'fail') {\n      const failureDetails = Object.values(result.report)\n        .flat()\n        .map((failedValidation) => {\n          const errorMessages = failedValidation.errors\n            .map((error) => `${error.code}: ${error.message}`)\n            .join('; ');\n\n          return `[${failedValidation.metadataName}] ${failedValidation.flatEntityMinimalInformation.universalIdentifier ?? failedValidation.flatEntityMinimalInformation.id ?? 'unknown'} -> ${errorMessages}`;\n        })\n        .join('\\n');\n\n      this.logger.error(\n        `Migration build failed for workspace ${workspaceId} while healing standard relation field labels/icons:\\n${failureDetails}`,\n      );\n\n      throw new Error(\n        `Migration failed for workspace ${workspaceId} while healing standard relation field labels/icons:\\n${failureDetails}`,\n      );\n    }\n\n    this.logger.log(\n      `Healed ${fieldsToUpdate.length} standard relation field(s) for workspace ${workspaceId}`,\n    );\n  }\n}\n","sourceCodeStart":139,"sourceCodeEnd":167,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-server/src/database/commands/upgrade-version-command/2-14/2-14-workspace-command-1799000040000-fix-standard-relation-field-labels-icons.command.ts#L139-L167","documentation":"Thrown by the 2.14 workspace upgrade command that heals standard relation field labels/icons when WorkspaceMigrationValidateBuildAndRunService.validateBuildAndRunLegacyWorkspaceMigration returns status 'fail'. The failureDetails string is assembled from result.report, listing each failedValidation's metadataName, universal identifier, and per-error code/message. It means one or more standard relation fields failed validation during the system build (isSystemBuild: true) that permits mutating system-owned label/icon.","triggerScenarios":"Running database:migrate:prod (or the workspace upgrade runner) on a workspace whose core.fieldMetadata rows for standard relation fields have drifted from the standard definition (mismatched label/icon, missing standard counterpart, or conflicting overrides). A previous partial migration, a hand-edited fieldMetadata row, or a stale standard metadata seed will cause validation to emit codes in failedValidation.errors and yield status 'fail'.","commonSituations":"Upgrading a long-running workspace across many versions where a prior command partially mutated labels; restoring a DB backup taken mid-migration; running a custom script that updated standard relation field label/icon outside the migration framework; standard metadata seed in the code image being newer than what the workspace's data expects.","solutions":["Read the logged failureDetails (printed just before the throw) to see exactly which metadataName + universal identifier + error codes are failing, and correct those core.fieldMetadata rows.","Verify the standard metadata seed bundled in the running image matches the version the workspace was last upgraded to; rebuild/redeploy the server image if it is stale.","Re-run with the command's isDryRun path (or wrap the call) to confirm the computed fieldsToUpdate and the standard counterparts line up before applying.","If a single workspace is irreparable, isolate it (mark suspended) so the runner continues with other workspaces, then repair its fieldMetadata rows manually and re-run."],"exampleFix":"// before: standard relation field row drifted\ncore.fieldMetadata: { label: 'Old Label', icon: null }\n// after: align with standard seed, then re-run upgrade\ncore.fieldMetadata: { label: 'Company' /* matches standard */, icon: 'IconBuilding' }","handlingStrategy":"validation","validationCode":"// Before running the upgrade, confirm standard relation fields in the workspace\n// match the standard seed for label/icon (the only fields this command mutates).\nconst drifted = await dataSource.query(`\n  SELECT f.\"id\", f.\"label\", f.\"icon\", s.\"label\" AS std_label, s.\"icon\" AS std_icon\n  FROM core.\"fieldMetadata\" f\n  JOIN core.\"objectMetadata\" o ON o.\"id\" = f.\"objectMetadataId\"\n  JOIN metadata.\"standardFieldMetadata\" s ON s.\"id\" = f.\"standardFieldMetadataId\"\n  WHERE o.\"isCustom\" = false AND f.\"type\" IN ('RELATION')\n    AND (f.\"label\" IS DISTINCT FROM s.\"label\" OR f.\"icon\" IS DISTINCT FROM s.\"icon\")\n`);\n// empty => command will no-op or succeed; non-empty => review rows first","typeGuard":"function isValidationFailReport(\n  r: unknown,\n): r is { status: 'fail'; report: Record<string, Array<{ metadataName: string; errors: Array<{ code: string; message: string }>; flatEntityMinimalInformation: { universalIdentifier?: string; id?: string } }>> } {\n  return typeof r === 'object' && r !== null && (r as any).status === 'fail' && typeof (r as any).report === 'object';\n}","tryCatchPattern":"// Workspace commands run inside the upgrade runner; wrap the runner invocation\n// and record which workspace/command failed, then continue or stop per policy.\ntry {\n  await upgradeRunner.runWorkspaceCommand(workspaceId, command);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Migration failed for workspace')) {\n    await upgradeAudit.recordFailure(workspaceId, command.id, err.message);\n    throw err; // surface to runner; do not swallow\n  }\n  throw err;\n}","preventionTips":["Never edit core.fieldMetadata rows for standard relation fields outside the migration framework.","Run database:migrate:prod in a maintenance window per workspace to avoid mid-mutation drift.","Always deploy the matching standard seed and command code together (single image build).","Use isDryRun / preview paths to inspect the computed fieldsToUpdate before applying."],"tags":["migration","workspace-upgrade","metadata-validation","standard-relation"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}