{"record":{"id":"194769807289e7b9","repo":"MemPalace/mempalace","slug":"unknown-job-id-job-id","errorCode":null,"errorMessage":"unknown job id: {job_id}","messagePattern":"unknown job id: (.+?)","errorType":"exception","errorClass":"DaemonError","httpStatus":null,"severity":"error","filePath":"mempalace/daemon.py","lineNumber":605,"sourceCode":"                    error_json = ?\n                WHERE id = ? AND state = 'running'\n                  AND (? IS NULL OR started_at = ?)\n                \"\"\",\n                (\n                    json.dumps(error or {}, ensure_ascii=False) if error else None,\n                    job_id,\n                    claimed_started_at,\n                    claimed_started_at,\n                ),\n            )\n            row = conn.execute(\"SELECT * FROM jobs WHERE id = ?\", (job_id,)).fetchone()\n            return self._row_to_job(row)\n\n    def get(self, job_id: str) -> Job:\n        with self._lock, self._connect() as conn:\n            row = conn.execute(\"SELECT * FROM jobs WHERE id = ?\", (job_id,)).fetchone()\n            if row is None:\n                raise DaemonError(f\"unknown job id: {job_id}\")\n            return self._row_to_job(row)\n\n    def list(self, limit: int = 20) -> list[Job]:\n        with self._lock, self._connect() as conn:\n            rows = conn.execute(\n                \"SELECT * FROM jobs ORDER BY created_at DESC LIMIT ?\",\n                (max(1, int(limit)),),\n            ).fetchall()\n            return [self._row_to_job(row) for row in rows]\n\n    def counts(self) -> dict[str, int]:\n        with self._lock, self._connect() as conn:\n            rows = conn.execute(\"SELECT state, COUNT(*) AS n FROM jobs GROUP BY state\").fetchall()\n            return {str(row[\"state\"]): int(row[\"n\"]) for row in rows}\n\n    @staticmethod\n    def _row_to_job(row: sqlite3.Row) -> Job:\n        def _loads(value):","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/daemon.py#L587-L623","documentation":"DaemonError from QueueStore.get() (mempalace/daemon.py:605): a SELECT on the jobs table for the given id returned no row. Job ids are minted at submit time and persisted in queue.sqlite3, so this means the id was never issued by this daemon's queue, or the queue database was reset/rotated since.","triggerScenarios":"Calling client.get_job(job_id) with a typo'd or truncated id; polling a job id from a previous daemon incarnation after the queue.sqlite3 was recreated; a job id from a different palace_path whose state dir hosts a separate queue; pruned/compacted job rows.","commonSituations":"Persisting job ids across daemon restarts in a hook or script and resuming after the state dir was rebuilt; copy-pasting ids from logs of a different environment; long-running orchestrators holding stale handles.","solutions":["Re-check the job id against the value returned from submit(); print it verbatim rather than hand-copying.","Use client.list_jobs() (QueueStore.list) to confirm the id exists in the current queue.","If the queue was reset, treat the missing job as lost and resubmit the work.","Confirm you are talking to the same palace_path/state dir that accepted the submission."],"exampleFix":"# before\njob = client.get_job(\"job-123\")  # typo / stale id\n\n# after\nresult = client.submit(\"index\", payload)\njob = client.wait_for_job(result[\"job_id\"], timeout=30)  # use the returned id","handlingStrategy":"validation","validationCode":"ids = {job[\"id\"] for job in client.list_jobs(limit=100)}\nif job_id not in ids:\n    # resubmit or skip — do not call get_job","typeGuard":"import re\n\ndef is_job_id(value: object) -> bool:\n    return isinstance(value, str) and bool(re.fullmatch(r\"[A-Za-z0-9_-]+\", value))","tryCatchPattern":"from mempalace.daemon import DaemonError\n\ntry:\n    job = client.get_job(job_id)\nexcept DaemonError:\n    # id never issued by this queue (reset/typo/other palace) — resubmit work\n    result = client.submit(kind, payload)","preventionTips":["Always keep the job id returned by submit(); never reconstruct ids by hand.","Scope stored job ids to a single palace_path and daemon lifetime.","Handle missing ids as lost work and resubmit idempotently (use dedupe_key)."],"tags":["daemon","queue","jobs","not-found"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}