n8n-io/n8n · error · TypeORMError

Column "${columnOrName}" was not found in table "${table.nam

Error message

Column "${columnOrName}" was not found in table "${table.name}"

What it means

dropColumn() resolves the column by name against the cached table metadata; if none matches it throws TypeORMError. You are trying to drop a column that does not exist in the table definition TypeORM has loaded.

Source

Thrown at packages/@n8n/typeorm/src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts:664

				changedTable.columns[changedTable.columns.indexOf(originalColumn)] =
					changedColumnSet.newColumn;
		});

		await this.recreateTable(changedTable, table);
	}

	/**
	 * Drops column in the table.
	 */
	async dropColumn(tableOrName: Table | string, columnOrName: TableColumn | string): Promise<void> {
		const table = InstanceChecker.isTable(tableOrName)
			? tableOrName
			: await this.getCachedTable(tableOrName);
		const column = InstanceChecker.isTableColumn(columnOrName)
			? columnOrName
			: table.findColumnByName(columnOrName);
		if (!column)
			throw new TypeORMError(`Column "${columnOrName}" was not found in table "${table.name}"`);

		await this.dropColumns(table, [column]);
	}

	/**
	 * Drops the columns in the table.
	 */
	async dropColumns(tableOrName: Table | string, columns: TableColumn[] | string[]): Promise<void> {
		const table = InstanceChecker.isTable(tableOrName)
			? tableOrName
			: await this.getCachedTable(tableOrName);

		// clone original table and remove column and its constraints from cloned table
		const changedTable = table.clone();
		columns.forEach((column: TableColumn | string) => {
			const columnInstance = InstanceChecker.isTableColumn(column)
				? column
				: table.findColumnByName(column);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Verify the column still exists in the live schema before dropping.
  2. Make the drop idempotent — check existence first.
  3. Re-fetch the table via getTable()/getCachedTable() if metadata may be stale.
  4. Use up() that guards against already-applied state.

Example fix

// before
await queryRunner.dropColumn('user', 'legacyField');

// after
const table = await queryRunner.getTable('user');
if (table?.findColumnByName('legacyField')) {
  await queryRunner.dropColumn(table!, 'legacyField');
}
Defensive patterns

Strategy: validation

Validate before calling

const table = await queryRunner.getTable('user');
if (table?.findColumnByName('legacyField')) {
  await queryRunner.dropColumn(table!, 'legacyField');
}

Type guard

const columnExists = async (qr: QueryRunner, tableName: string, col: string): Promise<boolean> =>
  Boolean((await qr.getTable(tableName))?.findColumnByName(col));

Prevention

When it happens

Trigger: Calling dropColumn(table, 'colName') where 'colName' is not a column in the cached table.

Common situations: Re-running a migration that already dropped the column, typo in the name, a prior migration renamed it, or stale cached metadata.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/d5ca2eb946eb8e91. Report an issue: GitHub.