{"record":{"id":"e78141e56d84e72a","repo":"HKUDS/DeepTutor","slug":"unknown-layer-layer-r-e78141","errorCode":null,"errorMessage":"unknown layer {layer!r}","messagePattern":"unknown layer (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/memory/consolidator/modes/dedup.py","lineNumber":209,"sourceCode":"\n    return DedupResult(\n        layer=layer,\n        key=key,\n        iterations_run=min(iters, (i + 1) if iters else 0),\n        edits_applied=total_applied,\n        converged_early=converged,\n    )\n\n\n# ── Helpers ─────────────────────────────────────────────────────────────\n\n\ndef _path_for(layer: str, key: str):\n    if layer == \"L2\":\n        return paths.l2_file(key)  # type: ignore[arg-type]\n    if layer == \"L3\":\n        return paths.l3_file(key)  # type: ignore[arg-type]\n    raise ValueError(f\"unknown layer {layer!r}\")\n\n\ndef _default_title(layer: str, key: str) -> str:\n    if layer == \"L2\":\n        return f\"{key} memory\"\n    return {\n        \"recent\": \"Recent summary\",\n        \"profile\": \"User profile\",\n        \"scope\": \"Knowledge scope\",\n        \"preferences\": \"Preferences\",\n    }.get(key, f\"{key} memory\")\n\n\ndef _render_with_numbers(view) -> str:\n    width = max(2, len(str(len(view.lines))))\n    return \"\\n\".join(f\"{line.number:>{width}}: {line.text}\" for line in view.lines)\n\n","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/memory/consolidator/modes/dedup.py#L191-L227","documentation":"dedup's _path_for maps a layer string to the corresponding memory file path and only accepts 'L2' and 'L3'. Any other value raises ValueError, because there is no file path for an unknown layer.","triggerScenarios":"The dedup pipeline (_run_dedup_inner) invoking _path_for with a layer string that isn't exactly 'L2' or 'L3' — lowercase variants, 'L1', or whitespace-padded input.","commonSituations":"Passing user-typed or config-file layer values straight into the dedup API; casing drift after refactoring shared layer constants.","solutions":["Pass exactly 'L2' or 'L3'","Validate/normalize the layer string at your entry point (strip + upper + membership check)","Share a single Layer literal/enum across dedup, merge, update, and audit call sites"],"exampleFix":"# before\nawait run_dedup(\"l2\", key)\n# after\nawait run_dedup(\"L2\", key)","handlingStrategy":"type-guard","validationCode":"assert layer in (\"L2\", \"L3\"), f\"bad layer {layer!r}\"","typeGuard":"from typing import Literal, TypeGuard\n\nLayer = Literal[\"L2\", \"L3\"]\n\ndef is_layer(v: object) -> TypeGuard[Layer]:\n    return isinstance(v, str) and v in (\"L2\", \"L3\")","tryCatchPattern":null,"preventionTips":["Share one Layer literal across dedup/merge/update/audit call sites","Reject unvalidated layer input at the CLI/API edge"],"tags":["memory","dedup","dispatch","argument-validation"],"backgroundTag":"unknown-layer-argument","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}