{"record":{"id":"c27268bb7774a405","repo":"immich-app/immich","slug":"unable-to-determine-worker-type","errorCode":null,"errorMessage":"Unable to determine worker type","messagePattern":"Unable to determine worker type","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"server/src/repositories/event.repository.ts","lineNumber":167,"sourceCode":"\n@Injectable()\nexport class EventRepository {\n  private emitHandlers: EmitHandlers = {};\n\n  constructor(\n    private moduleRef: ModuleRef,\n    private configRepository: ConfigRepository,\n    private logger: LoggingRepository,\n  ) {\n    this.logger.setContext(EventRepository.name);\n  }\n\n  setup({ services }: { services: (new (...args: any[]) => unknown)[] }) {\n    const reflector = this.moduleRef.get(Reflector, { strict: false });\n    const items: Item<EmitEvent>[] = [];\n    const worker = this.configRepository.getWorker();\n    if (!worker) {\n      throw new Error('Unable to determine worker type');\n    }\n\n    // discovery\n    for (const Service of services) {\n      const instance = this.moduleRef.get<any>(Service);\n      const ctx = Object.getPrototypeOf(instance);\n      for (const property of Object.getOwnPropertyNames(ctx)) {\n        const descriptor = Object.getOwnPropertyDescriptor(ctx, property);\n        if (!descriptor || descriptor.get || descriptor.set) {\n          continue;\n        }\n\n        const handler = instance[property];\n        if (typeof handler !== 'function') {\n          continue;\n        }\n\n        const event = reflector.get<EventConfig>(MetadataKey.EventConfig, handler);","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/repositories/event.repository.ts#L149-L185","documentation":"EventRepository.setup calls configRepository.getWorker() to know which worker it is running as. If that returns a falsy value (worker type could not be resolved from config), it throws Error('Unable to determine worker type') before event-handler discovery proceeds. The worker identity is required to decide which handlers to register.","triggerScenarios":"Starting Immich when the effective worker set is empty (e.g. IMMICH_WORKERS_INCLUDE and IMMICH_WORKERS_EXCLUDE cancel out to nothing) or the config bootstrap failed to assign a worker to the process.","commonSituations":"Misconfigured IMMICH_WORKERS_* env vars producing an empty set; running a process role that resolves to no recognized worker; config drift after an upgrade.","solutions":["Ensure at least one valid ImmichWorker remains after include/exclude (default is api + microservices).","Unset IMMICH_WORKERS_INCLUDE/EXCLUDE to fall back to defaults.","Check getWorker()/getEnv().workers to see what the process resolved to."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const inc = (process.env.IMMICH_WORKERS_INCLUDE ?? '').split(',').filter(Boolean);\nconst exc = new Set((process.env.IMMICH_WORKERS_EXCLUDE ?? '').split(',').filter(Boolean));\nconst effective = inc.filter((w) => !exc.has(w));\nif (effective.length === 0) throw new Error('Worker set is empty after include/exclude.');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not exclude all workers; keep at least api or microservices.","Leave worker env unset to use safe defaults.","Validate the effective worker set in CI for split-role deploys."],"tags":["configuration","workers","events","startup","nest"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}