MemPalace/mempalace · error · DaemonError
unknown job id: {job_id}
Error message
unknown job id: {job_id} What it means
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.
Source
Thrown at mempalace/daemon.py:605
error_json = ?
WHERE id = ? AND state = 'running'
AND (? IS NULL OR started_at = ?)
""",
(
json.dumps(error or {}, ensure_ascii=False) if error else None,
job_id,
claimed_started_at,
claimed_started_at,
),
)
row = conn.execute("SELECT * FROM jobs WHERE id = ?", (job_id,)).fetchone()
return self._row_to_job(row)
def get(self, job_id: str) -> Job:
with self._lock, self._connect() as conn:
row = conn.execute("SELECT * FROM jobs WHERE id = ?", (job_id,)).fetchone()
if row is None:
raise DaemonError(f"unknown job id: {job_id}")
return self._row_to_job(row)
def list(self, limit: int = 20) -> list[Job]:
with self._lock, self._connect() as conn:
rows = conn.execute(
"SELECT * FROM jobs ORDER BY created_at DESC LIMIT ?",
(max(1, int(limit)),),
).fetchall()
return [self._row_to_job(row) for row in rows]
def counts(self) -> dict[str, int]:
with self._lock, self._connect() as conn:
rows = conn.execute("SELECT state, COUNT(*) AS n FROM jobs GROUP BY state").fetchall()
return {str(row["state"]): int(row["n"]) for row in rows}
@staticmethod
def _row_to_job(row: sqlite3.Row) -> Job:
def _loads(value):View on GitHub (pinned to 06cb6987f0)
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.
Example fix
# before
job = client.get_job("job-123") # typo / stale id
# after
result = client.submit("index", payload)
job = client.wait_for_job(result["job_id"], timeout=30) # use the returned id Defensive patterns
Strategy: validation
Validate before calling
ids = {job["id"] for job in client.list_jobs(limit=100)}
if job_id not in ids:
# resubmit or skip — do not call get_job Type guard
import re
def is_job_id(value: object) -> bool:
return isinstance(value, str) and bool(re.fullmatch(r"[A-Za-z0-9_-]+", value)) Try / catch
from mempalace.daemon import DaemonError
try:
job = client.get_job(job_id)
except DaemonError:
# id never issued by this queue (reset/typo/other palace) — resubmit work
result = client.submit(kind, payload) Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- daemon is not running
- daemon is not running; job {args.job_id} is {job['state']}
- timed out waiting for job {job_id}
- daemon token not found for {palace_path}
- daemon endpoint not found
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/194769807289e7b9.
Report an issue: GitHub.