{"record":{"id":"4f1aa873a542c514","repo":"HKUDS/DeepTutor","slug":"unknown-layer-layer-r-4f1aa8","errorCode":null,"errorMessage":"unknown layer {layer!r}","messagePattern":"unknown layer (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/memory/consolidator/modes/merge.py","lineNumber":213,"sourceCode":"                if resolved is None or resolved in seen:\n                    continue\n                seen.add(resolved)\n                new_refs.append(resolved)\n            else:\n                if ref in seen:\n                    continue\n                seen.add(ref)\n                new_refs.append(ref)\n        entry.refs = new_refs\n    return migrated\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\n__all__ = [\"MergeResult\", \"run_merge\"]\n","sourceCodeStart":195,"sourceCodeEnd":228,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/memory/consolidator/modes/merge.py#L195-L228","documentation":"merge's _path_for is identical in spirit to dedup's: it resolves a memory file path per layer and only knows 'L2' and 'L3'. An unrecognized layer string raises ValueError inside run_merge before any merge work starts.","triggerScenarios":"Calling run_merge with a layer value other than the exact strings 'L2' or 'L3' (typos, casing, or an unvalidated external parameter).","commonSituations":"CLI or API exposure of the layer parameter without whitelist validation; inconsistent constants after upgrading the memory package.","solutions":["Pass exactly 'L2' or 'L3'","Whitelist-validate the layer parameter where it enters your program","Define a Literal['L2','L3'] type or enum shared with dedup/update/audit"],"exampleFix":"# before\nawait run_merge(layer=\"L3 \", keys=[...])\n# after\nawait run_merge(layer=\"L3\", keys=[...])","handlingStrategy":"type-guard","validationCode":"if layer not in (\"L2\", \"L3\"):\n    raise ValueError(\"layer must be 'L2' or 'L3'\")","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":["Whitelist-validate layer before calling run_merge","Strip and uppercase user-supplied layer values"],"tags":["memory","merge","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"}