immich-app/immich · warning

Skipping unknown job

Error message

Skipping unknown job: "${name}"

What it means

Job items dispatched to the queue are matched against the registered handlers map. If a job with the given name arrives with no registered handler, the repository logs this warning and returns JobStatus.Skipped instead of throwing. Usually means a job was enqueued under a name the running code doesn't know.

Solutions

  1. Update all Immich containers to the same version so job names and handlers match
  2. Clear stale jobs from the Redis queue (or let them drain/skip)
  3. Verify the microservices process started with the full handler registry (check for startup errors in the worker)
  4. Re-trigger the intended operation from the UI/API after upgrading

Example fix

// before: mixed versions
IMMICH_VERSION: v1.90.0  # server
IMMICH_VERSION: v1.89.0  # microservices
// after
IMMICH_VERSION: v1.90.0  # same tag for all services (use ${IMMICH_VERSION:-release})
Defensive patterns

Strategy: type-guard

Validate before calling

const knownJobs: JobName[] = Object.values(JobName);
function assertJobKnown(name: string): asserts name is JobName {
  if (!knownJobs.includes(name as JobName)) {
    throw new Error(`Unknown job name: ${name} — likely version skew between containers`);
  }
}

Type guard

function isKnownJob(name: string): name is JobName {
  return name in (jobRepository as any).handlers;
}

Try / catch

try {
  const status = await jobRepository.run(jobItem);
  if (status === JobStatus.Skipped) {
    logger.warn(`Job ${jobItem.name} skipped: handler missing — update all services to the same version`);
  }
} catch (err) { logger.error(err); }

Prevention

When it happens

Trigger: run() receives a JobItem whose name is not a key in this.handlers — e.g. a job name from a newer/older Immich version, or the worker process lacks the module that registers the handler.

Common situations: Version skew: server upgraded but microservices container still running old image (or vice versa); stale jobs left in Redis from a previous version with removed job names; custom/renamed job names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/6e1536cd15258ae0. Report an issue: GitHub.

Appendix: source

Thrown at server/src/repositories/job.repository.ts:140

      return;
    }

    if (this.microservicesPresent !== isPresent) {
      if (isPresent) {
        this.logger.log('Microservices worker connected.');
      } else {
        this.logger.warn(
          'No microservices worker is connected. Background jobs will not be processed until one is running.',
        );
      }
    }
    this.microservicesPresent = isPresent;
  }

  async run({ name, data }: JobItem) {
    const item = this.handlers[name as JobName];
    if (!item) {
      this.logger.warn(`Skipping unknown job: "${name}"`);
      return JobStatus.Skipped;
    }

    return item.handler(data);
  }

  setConcurrency(queueName: QueueName, concurrency: number) {
    const worker = this.workers[queueName];
    if (!worker) {
      this.logger.warn(`Unable to set queue concurrency, worker not found: '${queueName}'`);
      return;
    }

    worker.concurrency = concurrency;
  }

  async isActive(name: QueueName): Promise<boolean> {
    const queue = this.getQueue(name);

View on GitHub (pinned to e55ac299a4)