typeorm/typeorm · error · TypeORMError
Spanner does not support exclusion constraints.
Error message
Spanner does not support exclusion constraints.
What it means
Thrown by SpannerQueryRunner.createExclusionConstraint. Spanner has no exclusion constraints (a Postgres-specific feature used for things like range-overlap prevention via GiST operators). Every method in the exclusion-constraint family throws unconditionally for spanner because the underlying engine cannot honor the request.
Source
Thrown at src/driver/spanner/SpannerQueryRunner.ts:1464
ifExists?: boolean,
): Promise<void> {
const promises = checkConstraints.map((checkConstraint) =>
this.dropCheckConstraint(tableOrName, checkConstraint, ifExists),
)
await Promise.all(promises)
}
/**
* Creates new exclusion constraint.
*
* @param tableOrName
* @param exclusionConstraint
*/
async createExclusionConstraint(
tableOrName: Table | string,
exclusionConstraint: TableExclusion,
): Promise<void> {
throw new TypeORMError(
`Spanner does not support exclusion constraints.`,
)
}
/**
* Creates new exclusion constraints.
*
* @param tableOrName
* @param exclusionConstraints
*/
async createExclusionConstraints(
tableOrName: Table | string,
exclusionConstraints: TableExclusion[],
): Promise<void> {
throw new TypeORMError(
`Spanner does not support exclusion constraints.`,
)
}View on GitHub (pinned to 04ff4daedc)
Solutions
- Remove the exclusion constraint from the spanner migration path; it cannot be represented.
- Re-implement the exclusion business rule in application code or as a validating trigger/procedure spanner supports.
- Branch migrations per dialect: keep exclusion logic in a Postgres-only migration file gated by driver type.
- Search migrations with `rg -i "exclusion|ExclusionConstraint"` and delete/guard each hit before running on spanner.
Example fix
// before (migration copied from postgres)
await queryRunner.createExclusionConstraint('booking', new TableExclusion({
name: 'exclude_overlap',
expression: 'EXCLUDE USING gist (room_id WITH =, during WITH &&)',
}))
// after: drop it for spanner and enforce overlap checks in app code
if (dataSource.options.type !== 'spanner') {
await queryRunner.createExclusionConstraint('booking', /* ... */)
} Defensive patterns
Strategy: validation
Validate before calling
if (dataSource.options.type === 'spanner') {
throw new Error('Exclusion constraints unsupported on spanner; skipping')
} Type guard
function supportsExclusionConstraints(ds: DataSource): boolean {
return ds.options.type === 'postgres'
} Prevention
- Branch migration logic by dialect and only create exclusion constraints on postgres.
- Document range-overlap rules in app code for spanner targets.
- Lint migrations for TableExclusion usage before running on spanner.
When it happens
Trigger: Calling queryRunner.createExclusionConstraint(table, exclusion) on spanner, or running a migration/synchronize that derives an exclusion change from an entity/metadata (rare, since TypeORM entity decorators don't expose exclusion directly, but raw migration code or copied Postgres migrations can).
Common situations: Reusing a Postgres migration (e.g. a booking-overlap exclusion) verbatim on a spanner target. Tooling that diffs schemas across DBs and emits exclusion statements generically.
Related errors
- spanner driver does not support change table comment.
- MySql does not support exclusion constraints.
- Oracle does not support exclusion constraints.
- Check database queries are not supported by Spanner driver.
- Check schema queries are not supported by Spanner driver.
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/43cb985e5b213c52.json.
Report an issue: GitHub.