n8n-io/n8n · error · TypeORMError
Supplied index ${indexOrName} was not found in table ${table
Error message
Supplied index ${indexOrName} was not found in table ${table.name} What it means
dropIndex() resolves the index by name (or object) against the cached table; if none matches it throws TypeORMError. The index you are trying to drop does not exist in the table definition TypeORM has loaded.
Source
Thrown at packages/@n8n/typeorm/src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts:1019
* Creates a new indices
*/
async createIndices(tableOrName: Table | string, indices: TableIndex[]): Promise<void> {
const promises = indices.map((index) => this.createIndex(tableOrName, index));
await Promise.all(promises);
}
/**
* Drops an index from the table.
*/
async dropIndex(tableOrName: Table | string, indexOrName: TableIndex | string): Promise<void> {
const table = InstanceChecker.isTable(tableOrName)
? tableOrName
: await this.getCachedTable(tableOrName);
const index = InstanceChecker.isTableIndex(indexOrName)
? indexOrName
: table.indices.find((i) => i.name === indexOrName);
if (!index)
throw new TypeORMError(`Supplied index ${indexOrName} was not found in table ${table.name}`);
// old index may be passed without name. In this case we generate index name manually.
if (!index.name) index.name = this.generateIndexName(table, index);
const up = this.dropIndexSql(index);
const down = this.createIndexSql(table, index);
await this.executeQueries(up, down);
table.removeIndex(index);
}
/**
* Drops an indices from the table.
*/
async dropIndices(tableOrName: Table | string, indices: TableIndex[]): Promise<void> {
const promises = indices.map((index) => this.dropIndex(tableOrName, index));
await Promise.all(promises);
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Resolve the actual index name from the live schema via getTable().indices before dropping.
- Make the drop idempotent — check existence first.
- Re-fetch the table via getTable() if metadata may be stale.
Example fix
// before
await queryRunner.dropIndex('user', 'IDX_user_email');
// after
const table = await queryRunner.getTable('user');
if (table?.indices.some((i) => i.name === 'IDX_user_email')) {
await queryRunner.dropIndex(table!, 'IDX_user_email');
} Defensive patterns
Strategy: validation
Validate before calling
const table = await queryRunner.getTable('user');
if (table?.indices.some((i) => i.name === 'IDX_user_email')) {
await queryRunner.dropIndex(table!, 'IDX_user_email');
} Type guard
const indexExists = async (qr: QueryRunner, tableName: string, name: string): Promise<boolean> => Boolean((await qr.getTable(tableName))?.indices.some((i) => i.name === name));
Prevention
- Resolve the real index name from the live schema.
- Make index drops idempotent.
- Re-fetch table metadata when stale.
When it happens
Trigger: Calling dropIndex(table, 'indexName') where 'indexName' is not present in table.indices of the cached table.
Common situations: Re-running a migration that already dropped it, a typo in the index name, a prior migration removed it, or stale cached metadata.
Related errors
- Column "${oldTableColumnOrName}" was not found in the "${tab
- Column "${columnOrName}" was not found in table "${table.nam
- Column "${column}" was not found in table "${table.name}"
- Supplied unique constraint was not found in table ${table.na
- Supplied check constraint was not found in table ${table.nam
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f0257c6b42c99cea.
Report an issue: GitHub.