{"record":{"id":"ab2e9a38bef7fe4d","repo":"iflytek/astron-agent","slug":"lengthrange-must-contain-one-or-two-integers","errorCode":null,"errorMessage":"lengthRange must contain one or two integers","messagePattern":"lengthRange must contain one or two integers","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"core/knowledge/infra/ragflow/ragflow_utils.py","lineNumber":518,"sourceCode":"            separator: Separator list\n            titleSplit: Whether to split by title\n\n        Returns:\n            Parser configuration dictionary\n        \"\"\"\n        # RAGFlow's parser uses the configured maximum as its target chunk\n        # size. ``overlap`` and ``titleSplit`` are intentionally not forwarded:\n        # v0.20.5 has no overlap field, and title splitting is not equivalent\n        # to changing PDF layout recognition/OCR mode.\n        _ = overlap, titleSplit\n        if lengthRange is None:\n            chunk_token_num = 256\n        else:\n            if len(lengthRange) not in (1, 2) or any(\n                isinstance(value, bool) or not isinstance(value, int)\n                for value in lengthRange\n            ):\n                raise ValueError(\"lengthRange must contain one or two integers\")\n            if any(value <= 0 for value in lengthRange):\n                raise ValueError(\"lengthRange values must be greater than zero\")\n            if len(lengthRange) == 2 and lengthRange[0] > lengthRange[1]:\n                raise ValueError(\"lengthRange minimum cannot exceed maximum\")\n            chunk_token_num = lengthRange[-1]\n\n        # The Astron UI can send either a literal ``\\\\n`` or an actual newline.\n        # In RAGFlow v0.20.5, unquoted delimiter characters are independent;\n        # a multi-character delimiter must be wrapped in backticks.\n        normalized_separators = []\n        for value in separator or []:\n            normalized = value.replace(\"\\\\n\", \"\\n\")\n            if not normalized:\n                continue\n            normalized_separators.append(\n                normalized if len(normalized) == 1 else f\"`{normalized}`\"\n            )\n        if not any(\"\\n\" in value for value in normalized_separators):","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/knowledge/infra/ragflow/ragflow_utils.py#L500-L536","documentation":"build_parser_config validates the optional lengthRange parameter used to derive chunk_token_num, and raises ValueError when lengthRange is not a list of one or two true integers (bools are explicitly rejected because bool is a subclass of int in Python). It guards the RAGFlow parser config from malformed chunk-length settings.","triggerScenarios":"Calling build_parser_config with lengthRange=[] (empty), lengthRange=[1,2,3] (three values), or non-int entries like \"256\", 256.0, True, or None inside the list.","commonSituations":"JSON payloads from the Astron UI where numbers arrive as strings or floats; empty arrays sent when the user cleared a form field; booleans sneaking in via truthy config toggles; unvalidated passthrough of client config.","solutions":["Validate lengthRange on the API boundary: enforce list of 1-2 ints before calling build_parser_config","Coerce client values with int(value) and reject bools and non-numeric strings","Return a 400 to the caller listing the offending lengthRange value","Fall back to the default chunk_token_num (256) when lengthRange is absent or invalid"],"exampleFix":"// before\nconfig = build_parser_config(cfg={\"lengthRange\": payload.get(\"lengthRange\")})\n// after\nlr = payload.get(\"lengthRange\") or []\nif lr and (len(lr) not in (1, 2) or any(isinstance(v, bool) or not isinstance(v, int) for v in lr)):\n    raise HTTPException(400, \"lengthRange must contain one or two integers\")\nconfig = build_parser_config(cfg={\"lengthRange\": lr})","handlingStrategy":"validation","validationCode":"def validate_length_range(lr) -> list[int] | None:\n    if lr in (None, []):\n        return None\n    if not isinstance(lr, list) or len(lr) not in (1, 2):\n        raise ValueError(\"lengthRange must contain one or two integers\")\n    if any(isinstance(v, bool) or not isinstance(v, int) for v in lr):\n        raise ValueError(\"lengthRange must contain integers\")\n    return lr","typeGuard":"def is_valid_length_range(v) -> bool:\n    return (isinstance(v, list) and len(v) in (1, 2)\n            and all(isinstance(x, int) and not isinstance(x, bool) for x in v))","tryCatchPattern":"try:\n    config = build_parser_config(cfg=cfg)\nexcept ValueError as e:\n    if \"lengthRange\" in str(e):\n        cfg.pop(\"lengthRange\", None)  # fall back to default 256\n        config = build_parser_config(cfg=cfg)\n    else:\n        raise","preventionTips":["Pydantic-model (or equivalent) validate request bodies before business logic","Coerce JSON numbers (floats/strings) to int explicitly and reject bools","Never pass raw client dicts into config builders","Send [] / omit the field rather than partial junk when a range is unset"],"tags":["validation","ragflow","parser-config"],"backgroundTag":"invalid-argument-format","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}