immich-app/immich · error · BadRequestException
Invalid job name
Error message
Invalid job name
What it means
The manual job endpoint maps a ManualJobName enum value to a queue job via a switch (jobNameMap); the default case throws 400 BadRequestException 'Invalid job name' for anything that is not a known ManualJobName. This protects the queue from receiving an unknown job. Because the DTO already constrains the value to the enum, hitting this usually means the client sent a value not in the enum or the enum and client are out of sync.
Source
Thrown at server/src/services/job.service.ts:74
case ManualJobName.IntegrityChecksumFilesRefresh: {
return { name: JobName.IntegrityChecksumFiles, data: { refreshOnly: true } };
}
case ManualJobName.IntegrityMissingFilesDeleteAll: {
return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.MissingFile } };
}
case ManualJobName.IntegrityUntrackedFilesDeleteAll: {
return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.UntrackedFile } };
}
case ManualJobName.IntegrityChecksumFilesDeleteAll: {
return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.ChecksumFail } };
}
default: {
throw new BadRequestException('Invalid job name');
}
}
};
@Injectable()
export class JobService extends BaseService {
async create(dto: JobCreateDto): Promise<void> {
await this.jobRepository.queue(asJobItem(dto));
}
@OnEvent({ name: 'JobRun' })
async onJobRun(...[queueName, job]: ArgsOf<'JobRun'>) {
try {
await this.eventRepository.emit('JobStart', queueName, job);
const response = await this.jobRepository.run(job);
await this.eventRepository.emit('JobSuccess', { job, response });
if (response && typeof response === 'string' && [JobStatus.Success, JobStatus.Skipped].includes(response)) {
await this.onDone(job);View on GitHub (pinned to 199723261c)
Solutions
- Send only values listed in the ManualJobName enum for the server version you run (check the openapi spec under open-api/).
- Regenerate the client SDK from the running server's /openapi.json so enum values match.
- If you believe the job should exist, upgrade both server and client to the same Immich release.
- Validate the job name client-side against the enum before posting.
Example fix
// before
api.jobs.run({ name: 'someOldJobName' });
// after (value from current ManualJobName enum)
api.jobs.run({ name: JobName.StorageMigration }); Defensive patterns
Strategy: validation
Validate before calling
import { ManualJobName } from '@immich/sdk'; // from generated client
const validNames = new Set(Object.values(ManualJobName));
if (!validNames.has(dto.name as ManualJobName)) {
throw new Error(`Invalid job name: ${dto.name}`);
}
await api.jobApi.create(dto); Type guard
const isManualJobName = (n: string): n is ManualJobName => Object.values(ManualJobName).includes(n as ManualJobName);
Try / catch
try {
await api.jobApi.create(dto);
} catch (e) {
if (e.status === 400 && /Invalid job name/.test(e.message)) {
// regenerate SDK from server openapi, or pick a valid enum value
} else throw e;
} Prevention
- Regenerate the client SDK from the running server's OpenAPI spec.
- Validate enums client-side before posting.
- Keep server and client on the same Immich release.
When it happens
Trigger: POST /jobs with a name that is not in ManualJobName (e.g. a typo, a value from a newer/older API version, or a raw string bypassing DTO validation).
Common situations: API client built against a different Immich version than the server; hand-crafted request with an invalid job name; enum renamed/removed between versions.
Related errors
- assetIds, albumId, or userId is required
- Library ${id} not found
- Invalid import path: ${path.message}
- Notification not found
- User not found
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/14f449bc0e8e09ac.
Report an issue: GitHub.