{"record":{"id":"109d2d4082291a47","repo":"zylon-ai/private-gpt","slug":"unable-to-replace-text","errorCode":null,"errorMessage":"Unable to replace text","messagePattern":"Unable to replace text","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/tools/builders/text_editor_tool_builder.py","lineNumber":142,"sourceCode":"            ),\n        )\n\n    async def build_str_replace_tool(\n        self,\n        config: CodeExecutionSessionConfig,\n        name: str = TEXT_EDITOR_STR_REPLACE_TOOL_NAME,\n        type: str = TEXT_EDITOR_STR_REPLACE_TOOL_NAME + \"_v1\",\n        description: str = TEXT_EDITOR_STR_REPLACE_TOOL_FN.metadata.description,\n    ) -> ToolSpec:\n        async def str_replace(\n            path: str,\n            old_str: str,\n            new_str: str,\n        ) -> list[ResultContentBlockType]:\n            session = await self._session(config)\n            result = await session.str_replace(path, old_str, new_str)\n            if not result.success:\n                raise RuntimeError(result.error or \"Unable to replace text\")\n            output = _truncated(\n                result.output, self._settings.code_execution.max_output_bytes\n            )\n            return [TextEditorCodeExecutionStrReplaceResultBlock(lines=[output])]\n\n        return ToolSpec.from_defaults(\n            name=name,\n            type=type,\n            runtime=\"server\",\n            event_adapter=TextEditorCodeExecutionEventAdapter,\n            description=description,\n            async_fn=str_replace,\n            requirements=[ToolRequirements.SANDBOX],\n            execution_metadata=build_rebuild_metadata(\n                rebuild_text_editor_str_replace_tool,\n                {\n                    \"config\": config,\n                    \"name\": name,","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/tools/builders/text_editor_tool_builder.py#L124-L160","documentation":"RuntimeError from the str_replace tool: the session's str_replace(path, old_str, new_str) returned success=False. The raised message is result.error if the session provided detail, else 'Unable to replace text'. Typical session-side causes: file not found, old_str not present or appearing multiple times (ambiguous replacement).","triggerScenarios":"Calling str_replace on a path that does not exist in the sandbox, with an old_str that does not exactly match the file content (whitespace/indentation), or an old_str that occurs more than once and the provider requires uniqueness.","commonSituations":"LLM-hallucinated snippet that does not match the file; tabs-vs-spaces mismatch after a view/read of the file; editing a file in an expired or restarted sandbox session; race with another tool having rewritten the file.","solutions":["Read the current file content first (view tool) and copy old_str verbatim, preserving whitespace.","If the error message is generic, capture result.error to get the session's reason (not found vs no match vs multiple matches).","Recreate the session if it expired, then retry; ensure the path is the same one used to create/read the file."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# best pre-check: read the file first and confirm old_str occurs exactly once\nblocks = await view(path=path)\ncontent = blocks[0].content if blocks else \"\"\nassert content.count(old_str) == 1, \"old_str must match exactly once before str_replace\"","typeGuard":null,"tryCatchPattern":"try:\n    blocks = await str_replace(path=path, old_str=old_str, new_str=new_str)\nexcept RuntimeError as e:\n    detail = str(e) if str(e) != \"Unable to replace text\" else \"replace failed without detail\"\n    if \"not found\" in detail or \"match\" in detail:\n        # re-read the file and regenerate old_str from current content\n        pass\n    raise","preventionTips":["Always view the file immediately before str_replace and copy old_str verbatim (exact whitespace).","Ensure old_str is unique in the file; include surrounding context lines if it is ambiguous.","Keep view and replace in the same session turn to avoid content drift."],"tags":["text-editor","code-execution","str-replace","sandbox"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}