{"record":{"id":"3b898e7e6d8bb007","repo":"immich-app/immich","slug":"unknown-clip-model-newconfig-machinelearning-cl","errorCode":null,"errorMessage":"Unknown CLIP model: ${newConfig.machineLearning.clip.modelName}. Please check the model name for typos and confirm this is a supported model.","messagePattern":"Unknown CLIP model: (.+?)\\. Please check the model name for typos and confirm this is a supported model\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/smart-info.service.ts","lineNumber":28,"sourceCode":"\n@Injectable()\nexport class SmartInfoService extends BaseService {\n  @OnEvent({ name: 'ConfigInit', workers: [ImmichWorker.Microservices] })\n  async onConfigInit({ newConfig }: ArgOf<'ConfigInit'>) {\n    await this.init(newConfig);\n  }\n\n  @OnEvent({ name: 'ConfigUpdate', workers: [ImmichWorker.Microservices], server: true })\n  async onConfigUpdate({ oldConfig, newConfig }: ArgOf<'ConfigUpdate'>) {\n    await this.init(newConfig, oldConfig);\n  }\n\n  @OnEvent({ name: 'ConfigValidate' })\n  onConfigValidate({ newConfig }: ArgOf<'ConfigValidate'>) {\n    try {\n      getCLIPModelInfo(newConfig.machineLearning.clip.modelName);\n    } catch {\n      throw new Error(\n        `Unknown CLIP model: ${newConfig.machineLearning.clip.modelName}. Please check the model name for typos and confirm this is a supported model.`,\n      );\n    }\n  }\n\n  private async init(newConfig: SystemConfig, oldConfig?: SystemConfig) {\n    if (!isSmartSearchEnabled(newConfig.machineLearning)) {\n      return;\n    }\n\n    await this.databaseRepository.withLock(DatabaseLock.CLIPDimSize, async () => {\n      const { dimSize } = getCLIPModelInfo(newConfig.machineLearning.clip.modelName);\n      const dbDimSize = await this.databaseRepository.getDimensionSize('smart_search');\n      this.logger.verbose(`Current database CLIP dimension size is ${dbDimSize}`);\n\n      const modelChange =\n        oldConfig && oldConfig.machineLearning.clip.modelName !== newConfig.machineLearning.clip.modelName;\n      const isDimSizeChange = dbDimSize !== dimSize;","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/smart-info.service.ts#L10-L46","documentation":"SmartInfoService.onConfigValidate() runs during the ConfigValidate event. It calls getCLIPModelInfo(modelName) for the proposed machineLearning.clip.modelName; if that throws (model not in the known registry), the catch rethrows a descriptive Error (smart-info.service.ts:28). This blocks the config from being saved.","triggerScenarios":"Saving system config (PUT /system-config) with a machineLearning.clip.modelName that is not among the supported/known CLIP models, including typos and case mismatches if the lookup is case-sensitive.","commonSituations":"Pointing clip.modelName at a custom or newly downloaded model not yet registered, misspelling a model name, upgrading Immich without updating the ML server/models, or mismatched model availability between server and machine-learning containers.","solutions":["Use a modelName from the officially supported CLIP model list for your Immich version.","Check for typos and exact casing against the model registry.","If using a custom model, register/mount it in the machine-learning service and confirm it appears in the model list before referencing it.","Ensure the machine-learning container is running a compatible version that knows the model."],"exampleFix":"// before\n{ machineLearning: { clip: { modelName: 'clip-ViT-B32-mutuy' } } }\n// after\n{ machineLearning: { clip: { modelName: 'clip-ViT-B-32-multilingual-v1' } } }","handlingStrategy":"validation","validationCode":"const SUPPORTED_CLIP_MODELS = await fetchSupportedClipModels(); // from config options\nif (!SUPPORTED_CLIP_MODELS.includes(newConfig.machineLearning.clip.modelName)) {\n  throw new Error('Unsupported CLIP model name. Check the supported list.');\n}\nawait systemConfigApi.update(newConfig);","typeGuard":"const isKnownClipModel = (name: string, known: string[]): name is (typeof known)[number] =>\n  known.includes(name);","tryCatchPattern":"try {\n  await systemConfigApi.update(newConfig);\n} catch (e) {\n  if (/Unknown CLIP model/i.test(String((e as Error).message))) {\n    showConfigError('clip.modelName', 'Pick a supported CLIP model from the list.');\n  } else throw e;\n}","preventionTips":["Choose clip.modelName from the options exposed by getStorageTemplateOptions / config options endpoint.","After upgrades, verify custom model names are still registered.","Keep the machine-learning container version in sync with the server."],"tags":["machine-learning","clip","config","validation"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}