twentyhq/twenty · error · Error
Failed to create searchVector GIN index(es) for workspace ${
Error message
Failed to create searchVector GIN index(es) for workspace ${workspaceId} What it means
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.
Source
Thrown at 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:256
flatEntityToDelete: [],
flatEntityToUpdate: [],
},
},
workspaceId,
applicationUniversalIdentifier,
},
);
if (validateAndBuildResult.status === 'fail') {
this.logger.error(
`Failed to create searchVector GIN index(es) for application ${applicationUniversalIdentifier}:\n${JSON.stringify(
validateAndBuildResult,
null,
2,
)}`,
);
throw new Error(
`Failed to create searchVector GIN index(es) for workspace ${workspaceId}`,
);
}
}
}
private async flushIndexCacheAndBumpMetadataVersion(
workspaceId: string,
): Promise<void> {
const indexRelatedMetadataNames = [
'index',
...getMetadataRelatedMetadataNames('index'),
...getMetadataSerializedRelationNames('index'),
] as const;
const cacheKeysToFlush = [
...new Set(indexRelatedMetadataNames.map(getMetadataFlatEntityMapsKey)),
];
View on GitHub (pinned to 1f5dd2bbd2)
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
Example fix
// before: throws on first application failure, aborting all remaining applications
if (validateAndBuildResult.status === 'fail') {
throw new Error(`Failed to create searchVector GIN index(es) for workspace ${workspaceId}`);
}
// after: collect failures, continue, then report all at once
const failures = [];
// ... in the loop:
if (validateAndBuildResult.status === 'fail') {
failures.push({ applicationUniversalIdentifier, validateAndBuildResult });
continue;
}
// ... after the loop:
if (failures.length > 0) {
throw new Error(`Failed for ${failures.length} application(s): ${JSON.stringify(failures)}`);
} Defensive patterns
Strategy: retry
Validate before calling
// Before running, flush the workspace cache to ensure the builder sees fresh state
await workspaceCacheService.invalidateAndRecompute(workspaceId, [
'flatIndexMaps',
'flatObjectMetadataMaps',
'flatFieldMetadataMaps',
'flatApplicationMaps',
]);
// Verify no legacy universal identifiers remain that would collide
const legacyCount = await indexMetadataRepository.count({
where: { workspaceId, /* legacy identifier pattern */ },
});
if (legacyCount > 0) {
console.warn(`${legacyCount} legacy index rows may collide — re-own phase must succeed first`);
} Try / catch
// Retry once after flushing cache, since validate-build-run failures are often cache-staleness related
try {
await command.runOnWorkspace({ workspaceId, options: { dryRun: false } });
} catch (error) {
if (error.message.includes('Failed to create searchVector GIN index')) {
await workspaceCacheService.flush(workspaceId, ['flatIndexMaps']);
await command.runOnWorkspace({ workspaceId, options: { dryRun: false } });
} else {
throw error;
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to create searchFieldMetadata row(s) for workspace ${
- Failed to backfill imageIdentifierFieldMetadataId for worksp
- Failed to add coreWorkflowVersionId field for workspace ${wo
- Failed to add coreWorkflowId field for workspace ${workspace
- Failed to fix "Go to Roles Settings" command menu item path
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/a93a65f1ee8f9c8a.
Report an issue: GitHub.