{"record":{"id":"e31620e378390a82","repo":"HKUDS/DeepTutor","slug":"preferences-md-is-not-auto-consolidated-e31620","errorCode":null,"errorMessage":"preferences.md is not auto-consolidated","messagePattern":"preferences\\.md is not auto-consolidated","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/memory/consolidator/modes/update.py","lineNumber":374,"sourceCode":"        new_entry_ids=new_entry_ids,\n    )\n\n\n# ── L3 ──────────────────────────────────────────────────────────────────\n\n\nasync def _run_update_l3(\n    slot: L3Slot,\n    *,\n    language: str,\n    user_label: str,\n    budget: int,\n    llm_selection: dict | None,\n    on_event: OnEvent | None,\n    settings,\n) -> UpdateResult:\n    if slot == \"preferences\":\n        raise ValueError(\"preferences.md is not auto-consolidated\")\n\n    meta = load_l3_meta(slot)\n    l2_docs = _load_all_l2_docs()\n    entries_by_surface: dict[str, list[Entry]] = {}\n    seen_now: dict[str, set[str]] = {}\n    for surface, doc in l2_docs.items():\n        all_entries = doc.all_entries()\n        seen_now[surface] = {e.id for e in all_entries}\n        # Sort by id (ULID) ascending → roughly time-ascending.\n        new_entries = sorted(\n            (e for e in all_entries if e.id not in meta.seen_l2_entry_ids.get(surface, set())),\n            key=lambda e: e.id,\n        )\n        entries_by_surface[surface] = new_entries\n\n    new_count = sum(len(v) for v in entries_by_surface.values())\n    total_count = sum(len(d.all_entries()) for d in l2_docs.values())\n    await emit(","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/memory/consolidator/modes/update.py#L356-L392","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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"],"exampleFix":"// before\nfor slot in ALL_L3_SLOTS:\n    result = run_update(slot, ...)\n\n// after\nfor slot in ALL_L3_SLOTS:\n    if slot == \"preferences\":\n        continue  # user-authored; not auto-consolidated\n    result = run_update(slot, ...)","handlingStrategy":"validation","validationCode":"AUTO_CONSOLIDATABLE = {s for s in ALL_L3_SLOTS if s != \"preferences\"}\nassert slot in AUTO_CONSOLIDATABLE, f\"slot {slot!r} is not auto-consolidated\"","typeGuard":"def is_auto_consolidatable(slot: str) -> bool:\n    return slot != \"preferences\"","tryCatchPattern":"try:\n    result = run_update(slot, ...)\nexcept ValueError as e:\n    if \"not auto-consolidated\" in str(e):\n        logger.info(\"skipping consolidation for %s\", slot)\n    else:\n        raise","preventionTips":["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"],"tags":["memory","consolidation","slot","guard-clause"],"backgroundTag":"unsupported-operation-argument","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}