immich-app/immich · error · BadRequestException

{error.message}

Error message

{error.message}

What it means

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.

Source

Thrown at server/src/services/system-config.service.ts:71

    const { logLevel } = this.configRepository.getEnv();
    if (logLevel && !_.isEqual(toPlainObject(newConfig.logging), oldConfig.logging)) {
      throw new Error('Logging cannot be changed while the environment variable IMMICH_LOG_LEVEL is set.');
    }
  }

  async updateSystemConfig(dto: SystemConfigDto): Promise<SystemConfigDto> {
    const { configFile } = this.configRepository.getEnv();
    if (configFile) {
      throw new BadRequestException('Cannot update configuration while IMMICH_CONFIG_FILE is in use');
    }

    const oldConfig = await this.getConfig({ withCache: false });

    try {
      await this.eventRepository.emit('ConfigValidate', { newConfig: toPlainObject(dto), oldConfig });
    } catch (error) {
      this.logger.warn(`Unable to save system config due to a validation error: ${error}`);
      throw new BadRequestException(error instanceof Error ? error.message : error);
    }

    const newConfig = await this.updateConfig(dto);

    await this.eventRepository.emit('ConfigUpdate', { newConfig, oldConfig });

    return mapConfig(newConfig);
  }

  async getCustomCss(): Promise<string> {
    const { theme } = await this.getConfig({ withCache: false });
    return theme.customCss;
  }
}

View on GitHub (pinned to 199723261c)

Solutions

  1. Read the returned message to identify which validator rejected the change (logging, library, ML, etc.).
  2. Address the specific validator's constraint (see related errors 189/190 or library/template docs).
  3. Re-open the config diff and fix the offending field, then retry the PUT.
  4. Inspect server logs for the matching 'Unable to save system config due to a validation error' line for full context.
Defensive patterns

Strategy: try-catch

Try / catch

try { await configApi.update(newConfig); }
catch (e) {
  if (e instanceof BadRequestException) {
    // e.message is the underlying validator's message;
    // route it to the matching settings panel (logging, library, ML, etc.)
    surfaceFieldError(e.message);
  }
}

Prevention

When it happens

Trigger: 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.).

Common situations: Admin UI save fails because some subsystem rejected the new config; the exact reason is listener-specific and carried in error.message.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/ced27bccb22e0d1b. Report an issue: GitHub.