{"record":{"id":"37faeccf788adb47","repo":"invoke-ai/InvokeAI","slug":"unrecognized-job","errorCode":null,"errorMessage":"Unrecognized job","messagePattern":"Unrecognized job","errorType":"exception","errorClass":"UnknownJobIDException","httpStatus":null,"severity":"warning","filePath":"invokeai/app/services/download/download_default.py","lineNumber":287,"sourceCode":"        \"\"\"List all the jobs.\"\"\"\n        return list(self._jobs.values())\n\n    def prune_jobs(self) -> None:\n        \"\"\"Prune completed and errored queue items from the job list.\"\"\"\n        with self._lock:\n            to_delete = set()\n            for job_id, job in self._jobs.items():\n                if job.in_terminal_state:\n                    to_delete.add(job_id)\n            for job_id in to_delete:\n                del self._jobs[job_id]\n\n    def id_to_job(self, id: int) -> DownloadJob:\n        \"\"\"Translate a job ID into a DownloadJob object.\"\"\"\n        try:\n            return self._jobs[id]\n        except KeyError as excp:\n            raise UnknownJobIDException(\"Unrecognized job\") from excp\n\n    def cancel_job(self, job: DownloadJobBase) -> None:\n        \"\"\"\n        Cancel the indicated job.\n\n        If it is running it will be stopped.\n        job.status will be set to DownloadJobStatus.CANCELLED\n        \"\"\"\n        if job.status in [DownloadJobStatus.WAITING, DownloadJobStatus.RUNNING]:\n            job.cancel()\n\n    def cancel_all_jobs(self) -> None:\n        \"\"\"Cancel all jobs (those not in enqueued, running or paused state).\"\"\"\n        for job in self._jobs.values():\n            if not job.in_terminal_state:\n                self.cancel_job(job)\n\n    def wait_for_job(self, job: DownloadJobBase, timeout: int = 0) -> DownloadJobBase:","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/download/download_default.py#L269-L305","documentation":"id_to_job() looks up the numeric job ID in the service's _jobs dict and wraps a KeyError as UnknownJobIDException('Unrecognized job'). IDs are only valid while their job object is retained by the service.","triggerScenarios":"Calling id_to_job(id) with an ID that was never created, a stale ID from a previous service instance, or an ID whose job was purged/completed and removed.","commonSituations":"Clients caching job IDs across app restarts, polling status for a job after service restart, or typo'd/misread ID values.","solutions":["Verify the ID came from a job created by the same running service instance (download()/submit_download_job() return value)","Re-request the job list or re-submit the download if the service was restarted","Catch UnknownJobIDException and treat it as 'job no longer tracked', resubmitting if needed","Log the exact ID and compare against currently tracked jobs"],"exampleFix":"// before\njob = service.id_to_job(job_id)\n// after\n\ntry:\n    job = service.id_to_job(job_id)\nexcept UnknownJobIDException:\n    job = service.download(url, dest)  # re-enqueue","handlingStrategy":"try-catch","validationCode":"def job_id_known(service, job_id: int) -> bool:\n    return job_id in getattr(service, \"_jobs\", {})","typeGuard":"def is_valid_job_id(v: object) -> bool:\n    return isinstance(v, int) and v > 0","tryCatchPattern":"try:\n    job = service.id_to_job(job_id)\nexcept UnknownJobIDException:\n    logger.info(f\"job {job_id} no longer tracked; re-enqueueing\")\n    job = service.download(source, dest)","preventionTips":["Don't persist job IDs across app restarts; re-create downloads","Keep the job object reference alongside the ID in client code","Treat UnknownJobIDException as expected for completed/purged jobs","Verify IDs originate from the same running service instance"],"tags":["download","job-lookup","stale-id"],"backgroundTag":"unknown-job-id","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}