{"record":{"id":"d4edcc27e9df51cb","repo":"deepset-ai/haystack","slug":"tool-tool-name-failed-to-merge-outputs-into-s","errorCode":null,"errorMessage":"Tool '{tool.name}': failed to merge outputs into state. {e}","messagePattern":"Tool '(.+?)': failed to merge outputs into state\\. (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"haystack/components/agents/tool_calling.py","lineNumber":80,"sourceCode":"\ndef _merge_tool_outputs_into_state(tool: Tool, result: Any, state: State) -> None:\n    \"\"\"\n    Write tool outputs into State according to the tool's `outputs_to_state` mapping.\n\n    :raises RuntimeError: If writing an output value into the state fails.\n    \"\"\"\n    if not isinstance(result, dict):\n        return\n\n    for state_key, config in (tool.outputs_to_state or {}).items():\n        source_key = config.get(\"source\", None)\n        if source_key and source_key not in result:\n            continue\n        output_value = result.get(source_key) if source_key else result\n        try:\n            state.set(state_key, output_value, handler_override=config.get(\"handler\"))\n        except Exception as e:\n            raise RuntimeError(f\"Tool '{tool.name}': failed to merge outputs into state. {e}\") from e\n\n\ndef _result_to_string(result: Any) -> str:\n    \"\"\"\n    Convert a tool result to a string.\n\n    Strings are returned as-is; all other types are passed through a JSON serialization step to produce more readable\n    output, with a fallback to plain str() conversion if serialization fails.\n\n    :param result: The tool result to convert.\n    :returns: A string representation of the tool result.\n    \"\"\"\n    if isinstance(result, str):\n        return result\n    serializable = _serializable_value(value=result, use_placeholders=False)\n    try:\n        return json.dumps(serializable, ensure_ascii=False)\n    except Exception as error:","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/agents/tool_calling.py#L62-L98","documentation":"_merge_tool_outputs_into_state wraps any exception from State.set in this RuntimeError, chained with the original cause. It signals that a tool's output could not be merged into agent state — typically because the target state key is not in the schema or the handler failed.","triggerScenarios":"A tool's output mapping references a state_key absent from the schema (inner ValueError), or the configured handler raises inside state.set.","commonSituations":"Mismatch between tool output config and Agent state_schema after refactoring; a custom handler raising on unexpected value shapes.","solutions":["Read the chained cause (e) to see the underlying State error","Add the missing key to the Agent's state_schema or fix the tool's output state_key","Test the custom handler against the tool's actual output shape"],"exampleFix":"// before\ntool = Tool(..., outputs_to_state={\"summary\": {\"source_key\": \"sum\"}})\n# state_schema lacks \"summary\"\n// after\nagent = Agent(..., state_schema={..., \"summary\": {\"type\": str}})","handlingStrategy":"try-catch","validationCode":"def output_keys_declared(tool, schema):\n    for state_key in tool.outputs_to_state or {}:\n        if state_key not in schema:\n            raise ValueError(f\"State key '{state_key}' missing from schema\")","typeGuard":"def can_merge(tool, schema) -> bool:\n    return all(k in schema for k in (tool.outputs_to_state or {}))","tryCatchPattern":"try:\n    finalize_tool_result(tool, result, state, config)\nexcept RuntimeError as e:\n    if \"failed to merge outputs into state\" in str(e):\n        logging.warning(\"State merge failed for %s: %s\", tool.name, e.__cause__)\n        # fall back to returning tool output as string only\n    else:\n        raise","preventionTips":["Inspect e.__cause__ to find the real State error","Keep outputs_to_state mappings and state_schema definitions in one place","Unit-test each tool's merge path against the real schema","Validate custom handlers against actual tool output shapes"],"tags":["python","agent","state","tools","merge"],"backgroundTag":"state-merge-failure","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}