{"record":{"id":"14f449bc0e8e09ac","repo":"immich-app/immich","slug":"invalid-job-name","errorCode":null,"errorMessage":"Invalid job name","messagePattern":"Invalid job name","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/job.service.ts","lineNumber":74,"sourceCode":"\n    case ManualJobName.IntegrityChecksumFilesRefresh: {\n      return { name: JobName.IntegrityChecksumFiles, data: { refreshOnly: true } };\n    }\n\n    case ManualJobName.IntegrityMissingFilesDeleteAll: {\n      return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.MissingFile } };\n    }\n\n    case ManualJobName.IntegrityUntrackedFilesDeleteAll: {\n      return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.UntrackedFile } };\n    }\n\n    case ManualJobName.IntegrityChecksumFilesDeleteAll: {\n      return { name: JobName.IntegrityDeleteReportType, data: { type: IntegrityReport.ChecksumFail } };\n    }\n\n    default: {\n      throw new BadRequestException('Invalid job name');\n    }\n  }\n};\n\n@Injectable()\nexport class JobService extends BaseService {\n  async create(dto: JobCreateDto): Promise<void> {\n    await this.jobRepository.queue(asJobItem(dto));\n  }\n\n  @OnEvent({ name: 'JobRun' })\n  async onJobRun(...[queueName, job]: ArgsOf<'JobRun'>) {\n    try {\n      await this.eventRepository.emit('JobStart', queueName, job);\n      const response = await this.jobRepository.run(job);\n      await this.eventRepository.emit('JobSuccess', { job, response });\n      if (response && typeof response === 'string' && [JobStatus.Success, JobStatus.Skipped].includes(response)) {\n        await this.onDone(job);","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/job.service.ts#L56-L92","documentation":"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.","triggerScenarios":"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).","commonSituations":"API client built against a different Immich version than the server; hand-crafted request with an invalid job name; enum renamed/removed between versions.","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."],"exampleFix":"// before\napi.jobs.run({ name: 'someOldJobName' });\n// after (value from current ManualJobName enum)\napi.jobs.run({ name: JobName.StorageMigration });","handlingStrategy":"validation","validationCode":"import { ManualJobName } from '@immich/sdk'; // from generated client\nconst validNames = new Set(Object.values(ManualJobName));\nif (!validNames.has(dto.name as ManualJobName)) {\n  throw new Error(`Invalid job name: ${dto.name}`);\n}\nawait api.jobApi.create(dto);","typeGuard":"const isManualJobName = (n: string): n is ManualJobName =>\n  Object.values(ManualJobName).includes(n as ManualJobName);","tryCatchPattern":"try {\n  await api.jobApi.create(dto);\n} catch (e) {\n  if (e.status === 400 && /Invalid job name/.test(e.message)) {\n    // regenerate SDK from server openapi, or pick a valid enum value\n  } else throw e;\n}","preventionTips":["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."],"tags":["api","jobs","validation","enum","bad-request","immich","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}