n8n-io/n8n · error · TypeORMError

Sqlite does not support AUTOINCREMENT on composite primary k

Error message

Sqlite does not support AUTOINCREMENT on composite primary key

What it means

SQLite only permits AUTOINCREMENT on a single INTEGER PRIMARY KEY column. createTableSql() detects a composite primary key (more than one primary column) where at least one column is generated with the 'increment' strategy, and throws TypeORMError before generating any DDL. This is a schema-design constraint enforced up front.

Source

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

			}),
		);
	}

	/**
	 * Builds create table sql.
	 */
	protected createTableSql(
		table: Table,
		createForeignKeys?: boolean,
		temporaryTable?: boolean,
	): Query {
		const primaryColumns = table.columns.filter((column) => column.isPrimary);
		const hasAutoIncrement = primaryColumns.find(
			(column) => column.isGenerated && column.generationStrategy === 'increment',
		);
		const skipPrimary = primaryColumns.length > 1;
		if (skipPrimary && hasAutoIncrement)
			throw new TypeORMError(`Sqlite does not support AUTOINCREMENT on composite primary key`);

		const columnDefinitions = table.columns
			.map((column) => this.buildCreateColumnSql(column, skipPrimary))
			.join(', ');
		const [database] = this.splitTablePath(table.name);
		let sql = `CREATE TABLE ${this.escapePath(table.name)} (${columnDefinitions}`;

		let [databaseNew, tableName] = this.splitTablePath(table.name);
		const newTableName = temporaryTable
			? `${databaseNew ? `${databaseNew}.` : ''}${tableName.replace(/^temporary_/, '')}`
			: table.name;

		// need for `addColumn()` method, because it recreates table.
		table.columns
			.filter((column) => column.isUnique)
			.forEach((column) => {
				const isUniqueExist = table.uniques.some(
					(unique) => unique.columnNames.length === 1 && unique.columnNames[0] === column.name,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Split the auto-increment column out of the composite key — on SQLite it must be the sole primary column.
  2. For composite keys, drop the auto-increment strategy and assign IDs manually (or use a sequence/trigger).
  3. Redesign the entity so only one column is PRIMARY KEY if you need AUTOINCREMENT.
  4. If multi-column uniqueness is what you need, keep a single auto-increment PK and add a separate composite unique index instead.

Example fix

// before — composite PK with one auto-increment column
@PrimaryGeneratedColumn({ strategy: 'increment' })
id: number;
@PrimaryColumn() tenantId: number;

// after — single auto-increment PK, composite uniqueness via index
@PrimaryGeneratedColumn({ strategy: 'increment' })
id: number;
@Column() tenantId: number;
@Index('UQ_tenant_id', ['id', 'tenantId'], { unique: true })
Defensive patterns

Strategy: validation

Validate before calling

function isValidSqlitePrimaryKey(columns: { isPrimary: boolean; isGenerated: boolean; generationStrategy?: string }[]): boolean {
  const primaries = columns.filter((c) => c.isPrimary);
  const autoInc = primaries.some(
    (c) => c.isGenerated && c.generationStrategy === 'increment',
  );
  return !(primaries.length > 1 && autoInc);
}

if (!isValidSqlitePrimaryKey(entityColumns)) {
  throw new Error('SQLite cannot combine AUTOINCREMENT with a composite primary key');
}

Type guard

const hasCompositeAutoIncrementPk = (table: Table): boolean => {
  const primaries = table.columns.filter((c) => c.isPrimary);
  const autoInc = primaries.some(
    (c) => c.isGenerated && c.generationStrategy === 'increment',
  );
  return primaries.length > 1 && autoInc;
};

Prevention

When it happens

Trigger: Creating/recreating a table (CREATE TABLE path, including the table-copy used by ALTER workarounds) whose entity/metadata marks multiple columns as @PrimaryColumn and one of them as @PrimaryGeneratedColumn({ strategy: 'increment' }) / generationStrategy 'increment'.

Common situations: Porting a Postgres schema with a composite PK plus a serial column to SQLite; entities using a composite key that also mark an id column as auto-increment; test fixtures mirroring such a schema on SQLite.

Related errors


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