{"record":{"id":"ced27bccb22e0d1b","repo":"immich-app/immich","slug":"error-message","errorCode":null,"errorMessage":"{error.message}","messagePattern":"\\{error\\.message\\}","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/system-config.service.ts","lineNumber":71,"sourceCode":"    const { logLevel } = this.configRepository.getEnv();\n    if (logLevel && !_.isEqual(toPlainObject(newConfig.logging), oldConfig.logging)) {\n      throw new Error('Logging cannot be changed while the environment variable IMMICH_LOG_LEVEL is set.');\n    }\n  }\n\n  async updateSystemConfig(dto: SystemConfigDto): Promise<SystemConfigDto> {\n    const { configFile } = this.configRepository.getEnv();\n    if (configFile) {\n      throw new BadRequestException('Cannot update configuration while IMMICH_CONFIG_FILE is in use');\n    }\n\n    const oldConfig = await this.getConfig({ withCache: false });\n\n    try {\n      await this.eventRepository.emit('ConfigValidate', { newConfig: toPlainObject(dto), oldConfig });\n    } catch (error) {\n      this.logger.warn(`Unable to save system config due to a validation error: ${error}`);\n      throw new BadRequestException(error instanceof Error ? error.message : error);\n    }\n\n    const newConfig = await this.updateConfig(dto);\n\n    await this.eventRepository.emit('ConfigUpdate', { newConfig, oldConfig });\n\n    return mapConfig(newConfig);\n  }\n\n  async getCustomCss(): Promise<string> {\n    const { theme } = await this.getConfig({ withCache: false });\n    return theme.customCss;\n  }\n}\n","sourceCodeStart":53,"sourceCodeEnd":86,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/system-config.service.ts#L53-L86","documentation":"Re-thrown (as BadRequestException) by SystemConfigService.updateSystemConfig from the catch around the ConfigValidate event emit. The error.message of whatever a ConfigValidate listener threw (e.g. the IMMICH_LOG_LEVEL guard, machine-learning settings, library watchers) is surfaced verbatim, after a logger.warn of the same text.","triggerScenarios":"PUT /system-config where one or more ConfigValidate subscribers reject the new config (logging/env conflict, invalid OCR/machine-learning URL, duplicate storage templates, etc.).","commonSituations":"Admin UI save fails because some subsystem rejected the new config; the exact reason is listener-specific and carried in error.message.","solutions":["Read the returned message to identify which validator rejected the change (logging, library, ML, etc.).","Address the specific validator's constraint (see related errors 189/190 or library/template docs).","Re-open the config diff and fix the offending field, then retry the PUT.","Inspect server logs for the matching 'Unable to save system config due to a validation error' line for full context."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await configApi.update(newConfig); }\ncatch (e) {\n  if (e instanceof BadRequestException) {\n    // e.message is the underlying validator's message;\n    // route it to the matching settings panel (logging, library, ML, etc.)\n    surfaceFieldError(e.message);\n  }\n}","preventionTips":["Treat any PUT /system-config 400 as a domain-specific validation error, not a generic failure.","Log the exact error.message for support tickets; it identifies the rejecting subsystem.","Validate library/storage-template/ML fields locally before submit."],"tags":["config","validation","bad-request"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}