immich-app/immich · error

Unsupported vector extension

Error message

Unsupported vector extension: '${extension}'

What it means

getExtensionVersionRange maps each known vector extension to the version range Immich supports. The default branch is reached only when a VectorExtension value outside the known set is passed, which should be impossible with valid input — it is a defensive invariant check that flags unsupported/unknown extension identifiers.

Solutions

  1. Ensure only vector extension enum values are passed to getExtensionVersionRange
  2. Add a case to the switch for the new extension returning its supported version range
  3. Check immich release notes for dropped/renamed extensions and update your database/extension accordingly

Example fix

// before
return this.getExtensionVersionRange(DatabaseExtension.Postgres);
// after
return this.getExtensionVersionRange(DatabaseExtension.Vector);
Defensive patterns

Strategy: type-guard

Validate before calling

const VECTOR_EXTS = [DatabaseExtension.PgVectors, DatabaseExtension.VectorChord, DatabaseExtension.Vector] as const;
if (!VECTOR_EXTS.includes(extension as any)) throw new Error(`pass a vector extension, got ${extension}`);

Type guard

function isVectorExtension(ext: DatabaseExtension): ext is DatabaseExtension.PgVectors | DatabaseExtension.VectorChord | DatabaseExtension.Vector {
  return [DatabaseExtension.PgVectors, DatabaseExtension.VectorChord, DatabaseExtension.Vector].includes(ext as any);
}

Try / catch

try {
  range = await repo.getExtensionVersionRange(extension);
} catch (e) {
  if ((e as Error).message.startsWith('Unsupported vector extension')) range = null; // skip non-vector extensions
  else throw e;
}

Prevention

When it happens

Trigger: Calling getExtensionVersionRange (or code paths that resolve version ranges, e.g. extension install/upgrade logic) with a DatabaseExtension value that is not pgvectors, VectorChord, or Vector — e.g. an unhandled enum member added to the extension type but not to this switch.

Common situations: A contributor adds a new DatabaseExtension enum member but forgets to add a case in the switch; internal code passing DatabaseExtension.Postgres or another non-vector enum member by mistake.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/2d367829ff24cd97. Report an issue: GitHub.

Appendix: source

Thrown at server/src/repositories/database.repository.ts:98

  async getExtensionVersions(extensions: readonly DatabaseExtension[]): Promise<ExtensionVersion[]> {
    const { rows } = await sql<ExtensionVersion>`
      SELECT name, default_version as "availableVersion", installed_version as "installedVersion"
      FROM pg_available_extensions
      WHERE name in (${sql.join(extensions)})
    `.execute(this.db);
    return rows;
  }

  getExtensionVersionRange(extension: VectorExtension): string {
    switch (extension) {
      case DatabaseExtension.VectorChord: {
        return VECTORCHORD_VERSION_RANGE;
      }
      case DatabaseExtension.Vector: {
        return VECTOR_VERSION_RANGE;
      }
      default: {
        throw new Error(`Unsupported vector extension: '${extension}'`);
      }
    }
  }

  @GenerateSql()
  async getPostgresVersion(): Promise<string> {
    const { rows } = await sql<{ server_version: string }>`SHOW server_version`.execute(this.db);
    return rows[0].server_version;
  }

  getPostgresVersionRange(): string {
    return POSTGRES_VERSION_RANGE;
  }

  async createExtension(extension: DatabaseExtension): Promise<void> {
    this.logger.log(`Creating ${EXTENSION_NAMES[extension]} extension`);
    await sql`CREATE EXTENSION IF NOT EXISTS ${sql.raw(extension)} CASCADE`.execute(this.db);
    if (extension === DatabaseExtension.VectorChord) {

View on GitHub (pinned to e55ac299a4)