HKUDS/DeepTutor · error · ValueError
preferences.md is not auto-consolidated
Error message
preferences.md is not auto-consolidated
What it means
Raised by the L3 update consolidator when it is asked to consolidate the 'preferences' slot. The memory system deliberately excludes preferences.md from automatic consolidation because preferences are user-authored and must not be rewritten/merged by the pipeline. Any code path that routes slot=='preferences' into _run_update_l3 gets this hard rejection.
Source
Thrown at deeptutor/services/memory/consolidator/modes/update.py:374
new_entry_ids=new_entry_ids,
)
# ── L3 ──────────────────────────────────────────────────────────────────
async def _run_update_l3(
slot: L3Slot,
*,
language: str,
user_label: str,
budget: int,
llm_selection: dict | None,
on_event: OnEvent | None,
settings,
) -> UpdateResult:
if slot == "preferences":
raise ValueError("preferences.md is not auto-consolidated")
meta = load_l3_meta(slot)
l2_docs = _load_all_l2_docs()
entries_by_surface: dict[str, list[Entry]] = {}
seen_now: dict[str, set[str]] = {}
for surface, doc in l2_docs.items():
all_entries = doc.all_entries()
seen_now[surface] = {e.id for e in all_entries}
# Sort by id (ULID) ascending → roughly time-ascending.
new_entries = sorted(
(e for e in all_entries if e.id not in meta.seen_l2_entry_ids.get(surface, set())),
key=lambda e: e.id,
)
entries_by_surface[surface] = new_entries
new_count = sum(len(v) for v in entries_by_surface.values())
total_count = sum(len(d.all_entries()) for d in l2_docs.values())
await emit(View on GitHub (pinned to 3e82f13042)
Solutions
- Filter out the 'preferences' slot before invoking run_update; only auto-consolidatable slots (e.g. identity/life/facts per your slot registry) should be passed
- If preferences genuinely need updating, use the explicit memory ops API (ops.apply with AddOp/EditOp) or direct user-facing edit tooling instead of the consolidator
- Check the slot registry/meta (load_l3_meta) for which slots are auto-consolidatable and drive off that flag
Example fix
// before
for slot in ALL_L3_SLOTS:
result = run_update(slot, ...)
// after
for slot in ALL_L3_SLOTS:
if slot == "preferences":
continue # user-authored; not auto-consolidated
result = run_update(slot, ...) Defensive patterns
Strategy: validation
Validate before calling
AUTO_CONSOLIDATABLE = {s for s in ALL_L3_SLOTS if s != "preferences"}
assert slot in AUTO_CONSOLIDATABLE, f"slot {slot!r} is not auto-consolidated" Type guard
def is_auto_consolidatable(slot: str) -> bool:
return slot != "preferences" Try / catch
try:
result = run_update(slot, ...)
except ValueError as e:
if "not auto-consolidated" in str(e):
logger.info("skipping consolidation for %s", slot)
else:
raise Prevention
- Maintain an explicit allowlist of consolidatable slots instead of iterating all slots
- Keep preferences.md edits on the user-facing memory tool path, never the consolidator
When it happens
Trigger: Calling run_update (or the consolidator manager's update mode) with slot='preferences'; e.g. enumerating L3 slots and forwarding each one to the update mode without filtering out 'preferences'.
Common situations: Writing a loop over all memory slots to consolidate them; adding a new L3 slot list that includes preferences; a UI/API layer exposing 'consolidate' for every slot indiscriminately.
Related errors
- preferences.md is not auto-consolidated
- {exc}
- preferences.md is not audited automatically
- unknown layer {layer!r}
- a run is already in progress for {layer}/{key}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/e31620e378390a82.
Report an issue: GitHub.