{"record":{"id":"0337104e2a6dab1a","repo":"HKUDS/DeepTutor","slug":"add-invalid-section-op-section-r","errorCode":null,"errorMessage":"add: invalid section {op.section!r}","messagePattern":"add: invalid section (.+?)","errorType":"validation","errorClass":"OpValidationError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/memory/ops.py","lineNumber":79,"sourceCode":"    reason: str = \"\"\n\n\nclass OpValidationError(Exception):\n    \"\"\"Raised when a batch fails pre-flight validation.\"\"\"\n\n\ndef _validate(doc: Document, ops: list[Op]) -> None:\n    edits: set[str] = set()\n    deletes: set[str] = set()\n\n    for op in ops:\n        if isinstance(op, AddOp):\n            if not op.text or len(op.text) > _MAX_TEXT_LEN:\n                raise OpValidationError(\n                    f\"add: text length must be 1..{_MAX_TEXT_LEN} (got {len(op.text)})\"\n                )\n            if not op.section or len(op.section) > _MAX_SECTION_LEN:\n                raise OpValidationError(f\"add: invalid section {op.section!r}\")\n            if not op.refs:\n                raise OpValidationError(\"add: refs must be non-empty\")\n            for ref in op.refs:\n                if not is_valid_ref(ref):\n                    raise OpValidationError(f\"add: malformed ref {ref!r}\")\n        elif isinstance(op, EditOp):\n            if not is_entry_id(op.target_id):\n                raise OpValidationError(f\"edit: malformed target_id {op.target_id!r}\")\n            if doc.find(op.target_id) is None:\n                raise OpValidationError(f\"edit: target_id {op.target_id} not found\")\n            if not op.new_text or len(op.new_text) > _MAX_TEXT_LEN:\n                raise OpValidationError(\n                    f\"edit: text length must be 1..{_MAX_TEXT_LEN} (got {len(op.new_text)})\"\n                )\n            if not op.new_refs:\n                raise OpValidationError(\"edit: refs must be non-empty\")\n            for ref in op.new_refs:\n                if not is_valid_ref(ref):","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/memory/ops.py#L61-L97","documentation":"OpValidationError raised in _validate when an AddOp's section is empty or exceeds _MAX_SECTION_LEN. The section names the heading/bucket the new entry is filed under in the memory document; blank or oversized section strings would corrupt the document structure, so they are rejected before any write.","triggerScenarios":"AddOp(text=..., section='' or a section string longer than _MAX_SECTION_LEN, refs=[...]) passed to ops.apply. Commonly an LLM hallucinating a verbose 'section' like a full sentence instead of a short label, or a default/None coerced to ''.","commonSituations":"Free-form LLM output used directly as section; UI text input without maxlength feeding section; renaming sections programmatically with generated strings; locale variants making labels longer than expected.","solutions":["Normalize the section to a fixed short vocabulary (e.g. strip, lowercase, map to known sections) before constructing AddOp","Enforce a client-side maxlength equal to _MAX_SECTION_LEN (import it from ops.py to stay in sync)","Reject/fallback to a default section like 'notes' when validation fails"],"exampleFix":"# before\nop = AddOp(text=note, section=llm_section, refs=[ref])\n\n# after\nsection = (llm_section or \"notes\").strip()[:_MAX_SECTION_LEN] or \"notes\"\nop = AddOp(text=note, section=section, refs=[ref])","handlingStrategy":"validation","validationCode":"from deeptutor.services.memory.ops import _MAX_SECTION_LEN\nsection = (raw_section or \"\").strip()\nif not (1 <= len(section) <= _MAX_SECTION_LEN):\n    section = \"notes\"","typeGuard":"def is_valid_section(section: str) -> bool:\n    return bool(section) and len(section) <= _MAX_SECTION_LEN","tryCatchPattern":"try:\n    ops.apply(doc, [op])\nexcept OpValidationError as e:\n    if \"invalid section\" in str(e):\n        op = replace(op, section=\"notes\")\n        ops.apply(doc, [op])\n    else:\n        raise","preventionTips":["Constrain LLM section output to a fixed short vocabulary","Set maxlength on any UI field feeding section","Map/normalize sections at the boundary of your system"],"tags":["validation","memory","ops","section"],"backgroundTag":"payload-validation-failed","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}