{"record":{"id":"e1f6885c16e4037b","repo":"zylon-ai/private-gpt","slug":"view-range-must-contain-exactly-two-integers","errorCode":null,"errorMessage":"view_range must contain exactly two integers","messagePattern":"view_range must contain exactly two integers","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/tools/builders/text_editor_tool_builder.py","lineNumber":84,"sourceCode":"        if session is None:\n            raise ValueError(\"code_execution provider is not configured.\")\n        return session\n\n    async def build_view_tool(\n        self,\n        config: CodeExecutionSessionConfig,\n        name: str = TEXT_EDITOR_VIEW_TOOL_NAME,\n        type: str = TEXT_EDITOR_VIEW_TOOL_NAME + \"_v1\",\n        description: str = TEXT_EDITOR_VIEW_TOOL_FN.metadata.description,\n    ) -> ToolSpec:\n        async def view(\n            path: str,\n            view_range: list[int] | None = None,\n        ) -> list[ResultContentBlockType]:\n            resolved_view_range: tuple[int, int] | None = None\n            if view_range is not None:\n                if len(view_range) != 2:\n                    raise ValueError(\"view_range must contain exactly two integers\")\n                resolved_view_range = (view_range[0], view_range[1])\n\n            session = await self._session(config)\n            result = await session.view(\n                path,\n                view_range=resolved_view_range,\n            )\n            if not result.success:\n                raise RuntimeError(result.error or \"Unable to view file\")\n            output = _truncated(\n                result.output, self._settings.code_execution.max_output_bytes\n            )\n            line_count = len(output.splitlines())\n            start_line = resolved_view_range[0] if resolved_view_range else 1\n            return [\n                TextEditorCodeExecutionViewResultBlock(\n                    content=output,\n                    num_lines=line_count,","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/tools/builders/text_editor_tool_builder.py#L66-L102","documentation":"ValueError in the view tool closure: when view_range is provided it must be a two-element [start_line, end_line]; the code checks len(view_range) != 2 before converting to a tuple for session.view. Any other length is rejected before any session round-trip.","triggerScenarios":"Calling the text editor view tool with view_range=[1], view_range=[], or view_range=[1, 10, 20]; only exactly two integers pass.","commonSituations":"LLM emits a single line number meaning 'show this line' instead of a range; client passes a slice object converted to a 3-arg list (start, stop, step); malformed JSON array from the agent.","solutions":["Pass exactly two integers [start_line, end_line] (1-based, inclusive per the tool schema).","For a single line, expand it: view_range=[n, n].","Constrain the tool schema so view_range is an array of exactly 2 items."],"exampleFix":"# before\nawait view(path=\"src/app.py\", view_range=[42])\n\n# after\nawait view(path=\"src/app.py\", view_range=[42, 42])","handlingStrategy":"validation","validationCode":"if view_range is not None:\n    if not (isinstance(view_range, list) and len(view_range) == 2):\n        raise ValueError(\"view_range must be [start_line, end_line]\")\nawait view(path=path, view_range=view_range)","typeGuard":"def is_valid_view_range(vr) -> bool:\n    return vr is None or (isinstance(vr, list) and len(vr) == 2 and all(isinstance(x, int) for x in vr))","tryCatchPattern":null,"preventionTips":["Always send a [start, end] pair; expand a single line n to [n, n].","In the tool schema, declare view_range as items: integer, minItems: 2, maxItems: 2."],"tags":["text-editor","validation","view-range"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}