MemPalace/mempalace · error · ValueError
artifact_ids references unknown artifact {artifact_id!r}
Error message
artifact_ids references unknown artifact {artifact_id!r} What it means
An id in artifact_ids does not exist in the artifacts table, so the event insert is rolled back. append_event validates referential integrity inside the same transaction — every referenced artifact must have been created first via put_artifact on the same Logstream database. The check runs per-id in insertion order and reports the first missing one.
Source
Thrown at mempalace/logstream.py:439
if not isinstance(artifact_ids, list) or not all(
isinstance(a, str) and a for a in artifact_ids
):
raise ValueError("artifact_ids must be a list of artifact id strings")
artifact_ids = list(dict.fromkeys(artifact_ids)) # dedup, keep order
event_id = _new_id("evt")
created_at = _utc_now_iso()
hlc = self._clock.tick()
with self._lock:
conn = self._conn()
with conn:
for artifact_id in artifact_ids:
found = conn.execute(
"SELECT 1 FROM artifacts WHERE id = ?", (artifact_id,)
).fetchone()
if not found:
raise ValueError(
f"artifact_ids references unknown artifact {artifact_id!r}"
)
cursor = conn.execute(
"INSERT INTO events (id, type, stream, room, from_agent, to_agent,"
" correlation_id, branch, base_commit, status, body, created_at,"
" metadata_json, origin_replica, hlc)"
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
event_id,
type,
stream,
room,
from_agent,
to_agent,
correlation_id,
branch,
base_commit,
status,View on GitHub (pinned to 06cb6987f0)
Solutions
- Create the artifact first: art = ls.put_artifact(...) then append_event(artifact_ids=[art['id']]).
- Verify existence with ls.get_artifact(aid) before appending and create it if missing.
- Confirm every writer/reader uses the same db_path — a stray logstream.sqlite3 elsewhere means the lookup runs against the wrong file.
Example fix
// before evt = ls.append_event(type="patch.ready", artifact_ids=["art_20250814_deadbeef"], ...) // after art = ls.put_artifact(kind="patch", content=diff_text, created_by="mac-codex") evt = ls.append_event(type="patch.ready", artifact_ids=[art["id"]], ...)
Defensive patterns
Strategy: validation
Validate before calling
def ensure_artifacts(ls, ids):
missing = []
for aid in ids:
if ls.get_artifact(aid) is None:
missing.append(aid)
return missing # empty means safe to append
missing = ensure_artifacts(ls, artifact_ids)
if missing:
raise RuntimeError(f"artifacts not yet present: {missing}") Try / catch
try:
evt = ls.append_event(..., artifact_ids=artifact_ids)
except ValueError as e:
if "unknown artifact" in str(e):
# artifact not replicated/created yet; retry after sync
time.sleep(poll_s)
evt = ls.append_event(..., artifact_ids=artifact_ids)
else:
raise Prevention
- Order operations: put_artifact first, capture its returned id, then append_event referencing it.
- In replicated setups, only reference artifacts that arrived with the same sync batch.
- Log the exact artifact id at creation so mismatches are debuggable.
When it happens
Trigger: append_event(artifact_ids=['art_...']) before put_artifact created it; a typo or truncated id; referencing an artifact written to a different db_path (another palace directory or replica); the artifact insert committed to a different database file after a path/config change.
Common situations: Producer/consumer ordering bugs where the event is appended before the artifact upload; multi-replica setups where an event referencing a remote artifact is applied before that artifact replicates; palace directory changed between calls.
Related errors
- kind={kind!r} is not one of: {allowed}
- content must be a non-empty string
- content contains null bytes
- content is {len(raw)} bytes; maximum is {self.max_artifact_b
- {field_name} must be a non-empty string
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/15591dffb6e4e04e.
Report an issue: GitHub.