{"record":{"id":"a93a65f1ee8f9c8a","repo":"twentyhq/twenty","slug":"failed-to-create-searchvector-gin-index-es-for-wo","errorCode":null,"errorMessage":"Failed to create searchVector GIN index(es) for workspace ${workspaceId}","messagePattern":"Failed to create searchVector GIN index\\(es\\) 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-1783529458169-reconcile-search-vector-gin-index-universal-identifier.command.ts","lineNumber":256,"sourceCode":"                flatEntityToDelete: [],\n                flatEntityToUpdate: [],\n              },\n            },\n            workspaceId,\n            applicationUniversalIdentifier,\n          },\n        );\n\n      if (validateAndBuildResult.status === 'fail') {\n        this.logger.error(\n          `Failed to create searchVector GIN index(es) for application ${applicationUniversalIdentifier}:\\n${JSON.stringify(\n            validateAndBuildResult,\n            null,\n            2,\n          )}`,\n        );\n\n        throw new Error(\n          `Failed to create searchVector GIN index(es) for workspace ${workspaceId}`,\n        );\n      }\n    }\n  }\n\n  private async flushIndexCacheAndBumpMetadataVersion(\n    workspaceId: string,\n  ): Promise<void> {\n    const indexRelatedMetadataNames = [\n      'index',\n      ...getMetadataRelatedMetadataNames('index'),\n      ...getMetadataSerializedRelationNames('index'),\n    ] as const;\n    const cacheKeysToFlush = [\n      ...new Set(indexRelatedMetadataNames.map(getMetadataFlatEntityMapsKey)),\n    ];\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-workspace-command-1783529458169-reconcile-search-vector-gin-index-universal-identifier.command.ts#L238-L274","documentation":"Thrown by the 2.20 searchVector GIN index reconciliation command during its applyBackfill phase. For each application that needs a missing GIN index, the command calls validateBuildAndRunWorkspaceMigration with index-creation operations. If the pipeline returns status 'fail', the full failure report is logged to logger.error (JSON-serialized), then a simpler error is thrown. The pipeline validates the index operations, builds migration steps, and executes them — failure means the index metadata could not be created.","triggerScenarios":"validateBuildAndRunWorkspaceMigration returns { status: 'fail', report: ... } when creating searchVector GIN index flat entities. Caused by: a duplicate universal identifier collision (legacy index survived re-own), a referenced object/field not existing in workspace metadata, stale workspace cache feeding invalid state to the builder, or a DB-level error during migration execution.","commonSituations":"The preceding re-own transaction (applyReOwn) partially failed or rolled back, leaving legacy index rows that collide with the deterministic identifiers; workspace cache is stale after a prior partial upgrade; concurrent workspace metadata modifications during the upgrade.","solutions":["Read the logger.error output — it contains JSON.stringify(validateAndBuildResult) with the exact failure reasons in the report","Flush and recompute the workspace cache, then retry: the command is idempotent (already-backfilled indexes are skipped)","If the report shows a universal identifier collision, verify the re-own phase completed: check indexMetadataRepository for legacy vs deterministic universalIdentifier values","Run with --dryRun to see which indexes the command intends to create without committing"],"exampleFix":"// before: throws on first application failure, aborting all remaining applications\nif (validateAndBuildResult.status === 'fail') {\n  throw new Error(`Failed to create searchVector GIN index(es) for workspace ${workspaceId}`);\n}\n\n// after: collect failures, continue, then report all at once\nconst failures = [];\n// ... in the loop:\nif (validateAndBuildResult.status === 'fail') {\n  failures.push({ applicationUniversalIdentifier, validateAndBuildResult });\n  continue;\n}\n// ... after the loop:\nif (failures.length > 0) {\n  throw new Error(`Failed for ${failures.length} application(s): ${JSON.stringify(failures)}`);\n}","handlingStrategy":"retry","validationCode":"// Before running, flush the workspace cache to ensure the builder sees fresh state\nawait workspaceCacheService.invalidateAndRecompute(workspaceId, [\n  'flatIndexMaps',\n  'flatObjectMetadataMaps',\n  'flatFieldMetadataMaps',\n  'flatApplicationMaps',\n]);\n\n// Verify no legacy universal identifiers remain that would collide\nconst legacyCount = await indexMetadataRepository.count({\n  where: { workspaceId, /* legacy identifier pattern */ },\n});\n\nif (legacyCount > 0) {\n  console.warn(`${legacyCount} legacy index rows may collide — re-own phase must succeed first`);\n}","typeGuard":null,"tryCatchPattern":"// Retry once after flushing cache, since validate-build-run failures are often cache-staleness related\ntry {\n  await command.runOnWorkspace({ workspaceId, options: { dryRun: false } });\n} catch (error) {\n  if (error.message.includes('Failed to create searchVector GIN index')) {\n    await workspaceCacheService.flush(workspaceId, ['flatIndexMaps']);\n    await command.runOnWorkspace({ workspaceId, options: { dryRun: false } });\n  } else {\n    throw error;\n  }\n}","preventionTips":["Run upgrade commands with --dryRun first to validate the operation shapes before committing","Ensure no concurrent workspace metadata modifications are running during the upgrade","Flush the relevant workspace cache keys before retrying a failed upgrade command","Check the logger.error JSON output for the exact failure report before retrying — it distinguishes validation failures from DB errors"],"tags":["metadata","upgrade-command","workspace-migration","validate-build-run","gin-index","search-vector"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}