immich-app/immich · warning · BadRequestException
error instanceof Error ? error.message : error
Error message
error instanceof Error ? error.message : error
What it means
When the ConfigValidate event listeners (e.g. onConfigValidate) reject the new admin config, updateAdminConfig catches the error, logs a warning, and rethrows the validation message as a BadRequestException so the client sees the reason the config was not saved.
Solutions
- Read the validation message in the response and fix the offending config section accordingly
- Check server logs for the 'Unable to save system config' warning with the underlying error
- Resubmit the config with the conflicting section reverted to its previous value
Example fix
// before
catch (error) { throw error }
// after (server behavior)
catch (error) {
logger.warn(`Unable to save system config: ${error}`);
throw new BadRequestException(error instanceof Error ? error.message : error);
}
// client: surface the message and correct the config Defensive patterns
Strategy: try-catch
Validate before calling
// client-side: validate config against known rules before submit
if (process.env.IMMICH_LOG_LEVEL && changedSections.includes('logging')) {
alert('Logging changes are blocked while IMMICH_LOG_LEVEL is set');
} Type guard
null
Try / catch
try {
await api.saveAdminConfig(dto);
} catch (e) {
if (e.status === 400) {
// e.message carries the listener validation error; show it to the user
showValidationError(e.message);
}
} Prevention
- Read the BadRequest message — it contains the exact validation reason
- Check server logs for 'Unable to save system config' warnings
- Validate config against env-var constraints before submission
When it happens
Trigger: Admin submits a system config that fails a ConfigValidate listener: e.g. changing logging while IMMICH_LOG_LEVEL is set, or any other listener-registered validation rule failing.
Common situations: Admin UI config save rejected due to env-var conflicts or invalid combinations; bulk config import containing sections that conflict with the environment.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- {error.message}
- assetIds, albumId, or userId is required
- At least two people are required for merging
- Cannot request to join your own cluster group
- Cannot update configuration while IMMICH_CONFIG_FILE is in…
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/f2816bb3604ff152.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/system-config.service.ts:96
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 updateAdminConfig(dto: AdminConfigDto): Promise<AdminConfigDto> {
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 mapAdminConfig(newConfig);
}
async getCustomCss(): Promise<string> {
const { theme } = await this.getConfig({ withCache: false });
return theme.customCss;
}
}
View on GitHub (pinned to e55ac299a4)