typeorm/typeorm · 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
Thrown by OracleQueryRunner.dropIndex when the supplied index name or TableIndex object cannot be matched in table.indices. The runner searches table.indices by .name; if nothing matches and ifExists is not true, it throws. This is purely a metadata-lookup failure against the driver's cached schema view.
Source
Thrown at src/driver/oracle/OracleQueryRunner.ts:2358
*
* @param tableOrName
* @param indexOrName
* @param ifExists
*/
async dropIndex(
tableOrName: Table | string,
indexOrName: TableIndex | string,
ifExists?: boolean,
): 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) {
if (ifExists) return
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.
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.
*
* @param tableOrName
* @param indices
* @param ifExistsView on GitHub (pinned to 04ff4daedc)
Solutions
- Pass ifExists: true as the third argument to tolerate a missing index.
- Verify the index name in ALL_INDICES/USER_INDICES or table.indices before dropping.
- Pass a TableIndex object whose .name matches the cached metadata rather than a bare string.
- Refresh cached metadata with getCachedTable if the schema was changed externally.
Example fix
// before
await queryRunner.dropIndex("users", "idx_users_email");
// after
await queryRunner.dropIndex("users", "idx_users_email", true); Defensive patterns
Strategy: validation
Validate before calling
const table = await queryRunner.getTable("users");
const idxName = "idx_users_email";
if ((table?.indices ?? []).some(i => i.name === idxName)) {
await queryRunner.dropIndex("users", idxName);
} Type guard
import { TableIndex } from "typeorm";
function isTableIndex(o: unknown): o is TableIndex {
return typeof o === "object" && o !== null && "name" in o && Array.isArray((o as any).columnNames);
} Prevention
- Pass ifExists:true for index drops that may already have run.
- Read index names from table.indices rather than hard-coding.
- Watch for Oracle identifier case sensitivity when matching names.
When it happens
Trigger: Calling queryRunner.dropIndex(table, "idx_name") where 'idx_name' is not present in table.indices[].name. Happens with typoed index names, dropping an index already removed, or naming-strategy-generated names that differ from the explicit string supplied.
Common situations: Generated index names that differ from hand-written migration strings; index already dropped by a prior sync; case sensitivity on Oracle identifiers; dropping indexes created outside TypeORM.
Related errors
- Supplied index ${indexOrName} was not found in table ${table
- Supplied index ${indexOrName} was not found in table ${table
- Column "${oldTableColumnOrName}" was not found in the ${this
- Column "${columnOrName}" was not found in table ${this.escap
- Supplied unique constraint was not found in table ${table.na
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/a636403697d517cb.json.
Report an issue: GitHub.