{"record":{"id":"fa8d74940bb23a1a","repo":"immich-app/immich","slug":"invalid-clip-dimension-size-dimsize","errorCode":null,"errorMessage":"Invalid CLIP dimension size: ${dimSize}","messagePattern":"Invalid CLIP dimension size: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/repositories/database.repository.ts","lineNumber":328,"sourceCode":"        .min(1)\n        .max(2 ** 16)\n        .safeParse(dimSize).success\n    ) {\n      this.logger.warn(`Could not retrieve dimension size of column '${column}' in table '${table}', assuming 512`);\n      return 512;\n    }\n    return dimSize;\n  }\n\n  async setDimensionSize(dimSize: number): Promise<void> {\n    if (\n      !z\n        .int()\n        .min(1)\n        .max(2 ** 16)\n        .safeParse(dimSize).success\n    ) {\n      throw new Error(`Invalid CLIP dimension size: ${dimSize}`);\n    }\n\n    // this is done in two transactions to handle concurrent writes\n    await this.db.transaction().execute(async (trx) => {\n      await sql`delete from ${sql.table('smart_search')}`.execute(trx);\n      await trx.schema.alterTable('smart_search').dropConstraint('dim_size_constraint').ifExists().execute();\n      await sql`alter table ${sql.table('smart_search')} add constraint dim_size_constraint check (array_length(embedding::real[], 1) = ${sql.lit(dimSize)})`.execute(\n        trx,\n      );\n    });\n\n    const vectorExtension = await this.getVectorExtension();\n    await this.db.transaction().execute(async (trx) => {\n      await sql`drop index if exists clip_index`.execute(trx);\n      await trx.schema\n        .alterTable('smart_search')\n        .alterColumn('embedding', (col) => col.setDataType(sql.raw(`vector(${dimSize})`)))\n        .execute();","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/repositories/database.repository.ts#L310-L346","documentation":"setDimensionSize reconfigures the smart_search table's embedding dimension for the CLIP model. The requested dimension must be an integer between 1 and 65536 (2^16) — the limit imposed by the halfvec/index representation. Invalid values (NaN, 0, negative, non-integers, >65536) throw before any schema change is made.","triggerScenarios":"Calling setDimensionSize with a dimSize that fails the zod check: 0, negative, non-integer, NaN, or above 65536 — typically from an environment/config value (e.g. MACHINE_LEARNING clip dimension) parsed incorrectly or from a mismatched ML model configuration.","commonSituations":"Setting a CLIP dimension that doesn't match the ML model's output (e.g. 512 for a 1152-dim model); an unset/empty env var parsed to NaN; custom model deployments whose embedding size differs from Immich's defaults.","solutions":["Ensure the value is a positive integer ≤ 65536 and matches the ML model's embedding size (e.g. 512, 768, 1152)","Check the MACHINE_LEARNING env/config for typos or empty values that parse to NaN","Verify the ML service's model actually outputs the configured dimension, then re-run smart search indexing","After fixing the dimension, let Immich recreate the smart_search index (it drops and rebuilds it automatically)"],"exampleFix":"// before\nawait repo.setDimensionSize(Number(process.env.CLIP_DIM)); // NaN when unset\n// after\nconst dim = Number(process.env.CLIP_DIM);\nif (Number.isInteger(dim) && dim >= 1 && dim <= 65536) await repo.setDimensionSize(dim);","handlingStrategy":"validation","validationCode":"if (!Number.isInteger(dimSize) || dimSize < 1 || dimSize > 65536) {\n  throw new Error(`dimSize must be an integer in [1, 65536], got ${dimSize}`);\n}","typeGuard":"const isValidDim = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 65536;","tryCatchPattern":"try {\n  await repo.setDimensionSize(dim);\n} catch (e) {\n  if ((e as Error).message.startsWith('Invalid CLIP dimension size')) {\n    dim = MODEL_OUTPUT_DIM; // fall back to the model's known embedding size\n    await repo.setDimensionSize(dim);\n  } else throw e;\n}","preventionTips":["Parse config values with a strict integer schema (zod) before use","Cross-check dimension against the deployed ML model's embedding size","Never pass raw/unparsed env strings to setDimensionSize"],"tags":["validation","database","clip","configuration"],"backgroundTag":"value-out-of-range","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}