{"record":{"id":"58ed16662d9fc3e1","repo":"run-llama/llama_index","slug":"could-not-extract-final-answer-from-input-text-i","errorCode":null,"errorMessage":"Could not extract final answer from input text: {input_text}","messagePattern":"Could not extract final answer from input text: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"llama-index-core/llama_index/core/agent/react/output_parser.py","lineNumber":40,"sourceCode":"    thought = (match.group(1) or match.group(2)).strip()\n    action = match.group(3).strip()\n    action_input = match.group(4).strip()\n    return thought, action, action_input\n\n\ndef action_input_parser(json_str: str) -> dict:\n    processed_string = re.sub(r\"(?<!\\w)\\'|\\'(?!\\w)\", '\"', json_str)\n    pattern = r'\"(\\w+)\":\\s*\"([^\"]*)\"'\n    matches = re.findall(pattern, processed_string)\n    return dict(matches)\n\n\ndef extract_final_response(input_text: str) -> Tuple[str, str]:\n    pattern = r\"\\s*Thought:(.*?)Answer:(.*?)(?:$)\"\n\n    match = re.search(pattern, input_text, re.DOTALL)\n    if not match:\n        raise ValueError(\n            f\"Could not extract final answer from input text: {input_text}\"\n        )\n\n    thought = match.group(1).strip()\n    answer = match.group(2).strip()\n    return thought, answer\n\n\ndef parse_action_reasoning_step(output: str) -> ActionReasoningStep:\n    \"\"\"\n    Parse an action reasoning step from the LLM output.\n    \"\"\"\n    # Weaker LLMs may generate ReActAgent steps whose Action Input are horrible JSON strings.\n    # `dirtyjson` is more lenient than `json` in parsing JSON strings.\n    import dirtyjson as json\n\n    thought, action, action_input = extract_tool_use(output)\n    json_str = extract_json_str(action_input)","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/agent/react/output_parser.py#L22-L58","documentation":"BaseKeyValueStore.put_all's default implementation only supports batch_size == 1; any caller requesting a larger batch against a store that did not override put_all gets NotImplementedError. Concrete stores (MongoDBKVStore, RedisKVStore, etc.) override this to do real batched writes; the base-class loop is a fallback that writes pairs one by one.","triggerScenarios":"Calling kvstore.put_all(kv_pairs, batch_size=8) on a store whose class only implements the abstract put/get/delete (e.g. a custom KV store or SimpleKVStore without a put_all override); passing DEFAULT_BATCH_SIZE from a config that is greater than 1.","commonSituations":"Writing a custom KVStore subclass and forgetting to override put_all while the docstore/index store layer tries batched ingestion; swapping a MongoDB-backed store for a minimal in-memory store in tests without implementing batching; configurations that tune batch_size for throughput.","solutions":["Call put_all without batch_size (default 1) so the base implementation's loop applies.","Override put_all in your custom store to chunk kv_pairs and delegate to self.put per chunk.","Use a built-in store that supports batching (SimpleKVStore, MongoDBKVStore, RedisKVStore) when batch writes matter.","If performance requires batching, implement put_all with the backend's native bulk API."],"exampleFix":"# before\nclass MyKVStore(BaseKeyValueStore):\n    ...\nstore.put_all(pairs, batch_size=64)  # NotImplementedError\n\n# after\nclass MyKVStore(BaseKeyValueStore):\n    def put_all(self, kv_pairs, collection=DEFAULT_COLLECTION, batch_size=1):\n        for key, val in kv_pairs:  # simple unbatched fallback\n            self.put(key, val, collection=collection)\nstore.put_all(pairs)  # default batch_size=1, works","handlingStrategy":"validation","validationCode":"if batch_size != 1 and type(kvstore).put_all is BaseKeyValueStore.put_all:\n    kvstore.put_all(kv_pairs)  # fall back to batch_size=1\nelse:\n    kvstore.put_all(kv_pairs, batch_size=batch_size)","typeGuard":"from llama_index.core.storage.kvstore.types import BaseKeyValueStore\n\ndef supports_batching(store: BaseKeyValueStore) -> bool:\n    return type(store).put_all is not BaseKeyValueStore.put_all","tryCatchPattern":"try:\n    kvstore.put_all(pairs, batch_size=64)\nexcept NotImplementedError:\n    kvstore.put_all(pairs)  # default batch_size=1","preventionTips":["Custom KV stores should override put_all even if just looping put().","Only pass batch_size > 1 to stores documented to support batching.","Feature-detect the override before requesting batched writes."],"tags":["kvstore","batching","not-implemented","custom-store"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}