HKUDS/DeepTutor · error · OpValidationError

add: invalid section {op.section!r}

Error message

add: invalid section {op.section!r}

What it means

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.

Source

Thrown at deeptutor/services/memory/ops.py:79

    reason: str = ""


class OpValidationError(Exception):
    """Raised when a batch fails pre-flight validation."""


def _validate(doc: Document, ops: list[Op]) -> None:
    edits: set[str] = set()
    deletes: set[str] = set()

    for op in ops:
        if isinstance(op, AddOp):
            if not op.text or len(op.text) > _MAX_TEXT_LEN:
                raise OpValidationError(
                    f"add: text length must be 1..{_MAX_TEXT_LEN} (got {len(op.text)})"
                )
            if not op.section or len(op.section) > _MAX_SECTION_LEN:
                raise OpValidationError(f"add: invalid section {op.section!r}")
            if not op.refs:
                raise OpValidationError("add: refs must be non-empty")
            for ref in op.refs:
                if not is_valid_ref(ref):
                    raise OpValidationError(f"add: malformed ref {ref!r}")
        elif isinstance(op, EditOp):
            if not is_entry_id(op.target_id):
                raise OpValidationError(f"edit: malformed target_id {op.target_id!r}")
            if doc.find(op.target_id) is None:
                raise OpValidationError(f"edit: target_id {op.target_id} not found")
            if not op.new_text or len(op.new_text) > _MAX_TEXT_LEN:
                raise OpValidationError(
                    f"edit: text length must be 1..{_MAX_TEXT_LEN} (got {len(op.new_text)})"
                )
            if not op.new_refs:
                raise OpValidationError("edit: refs must be non-empty")
            for ref in op.new_refs:
                if not is_valid_ref(ref):

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Normalize the section to a fixed short vocabulary (e.g. strip, lowercase, map to known sections) before constructing AddOp
  2. Enforce a client-side maxlength equal to _MAX_SECTION_LEN (import it from ops.py to stay in sync)
  3. Reject/fallback to a default section like 'notes' when validation fails

Example fix

# before
op = AddOp(text=note, section=llm_section, refs=[ref])

# after
section = (llm_section or "notes").strip()[:_MAX_SECTION_LEN] or "notes"
op = AddOp(text=note, section=section, refs=[ref])
Defensive patterns

Strategy: validation

Validate before calling

from deeptutor.services.memory.ops import _MAX_SECTION_LEN
section = (raw_section or "").strip()
if not (1 <= len(section) <= _MAX_SECTION_LEN):
    section = "notes"

Type guard

def is_valid_section(section: str) -> bool:
    return bool(section) and len(section) <= _MAX_SECTION_LEN

Try / catch

try:
    ops.apply(doc, [op])
except OpValidationError as e:
    if "invalid section" in str(e):
        op = replace(op, section="notes")
        ops.apply(doc, [op])
    else:
        raise

Prevention

When it happens

Trigger: 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 ''.

Common situations: 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.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/0337104e2a6dab1a. Report an issue: GitHub.