{"record":{"id":"268c508e90083913","repo":"datawhalechina/hello-agents","slug":"stage-payload-get-message","errorCode":null,"errorMessage":"{stage}失败：{payload.get('message', '未知工具错误')}","messagePattern":"\\{stage\\}失败：\\{payload\\.get\\('message', '未知工具错误'\\)\\}","errorType":"exception","errorClass":"WorkflowExecutionError","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/zenith191-RequirementClarifierAgent/src/workflow.py","lineNumber":157,"sourceCode":"        self, name: str, parameters: dict[str, object], stage: str\n    ) -> dict[str, object]:\n        \"\"\"通过官方 ToolRegistry 获取工具并解析其字符串协议。\"\"\"\n\n        tool = self.tool_registry.get_tool(name)\n        if tool is None:\n            raise WorkflowExecutionError(f\"{stage}失败：工具 {name} 未注册\")\n        try:\n            raw_result = tool.run(parameters)\n        except Exception as exc:\n            raise WorkflowExecutionError(f\"{stage}失败：工具执行异常：{exc}\") from exc\n        try:\n            payload = json.loads(raw_result)\n        except (TypeError, ValueError) as exc:\n            raise WorkflowExecutionError(f\"{stage}失败：工具返回的不是有效 JSON\") from exc\n        if not isinstance(payload, dict):\n            raise WorkflowExecutionError(f\"{stage}失败：工具结果必须是 JSON 对象\")\n        if not payload.get(\"ok\"):\n            raise WorkflowExecutionError(\n                f\"{stage}失败：{payload.get('message', '未知工具错误')}\"\n            )\n        return payload\n\n    def _clear_agent_histories(self) -> None:\n        \"\"\"避免多次运行时把上一条需求带入下一条需求。\"\"\"\n\n        for agent in (\n            self.team.analyst,\n            self.team.architect,\n            self.team.reviewer,\n            self.team.synthesizer,\n        ):\n            clear_history = getattr(agent, \"clear_history\", None)\n            if callable(clear_history):\n                clear_history()\n\n    @staticmethod","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/zenith191-RequirementClarifierAgent/src/workflow.py#L139-L175","documentation":"Raised by _run_tool when the parsed JSON object has a falsy 'ok' field — the tool succeeded at the protocol level but reported a logical failure. The message field from the payload is surfaced (falling back to '未知工具错误' when the tool omitted it), prefixed with the stage name.","triggerScenarios":"A tool returns {\"ok\": false, \"message\": \"query returned no rows\"}; any custom tool signalling failure via the ok flag; the tool returns {\"ok\": false} with no message key, yielding the '未知工具错误' fallback text.","commonSituations":"A search/lookup tool finds nothing for the model's arguments; an external dependency checked by the tool is down; validation inside the tool rejects the model-provided parameters.","solutions":["Treat the embedded message as the real error: it comes from the tool itself (e.g. 'no results'); fix the underlying condition or the arguments the model passed.","If 'no results' is expected and recoverable, change the tool to return ok:true with an empty result set so the workflow can continue.","Improve tool descriptions/schemas so the model supplies valid arguments that avoid the failure."],"exampleFix":"# before (tool)\nreturn json.dumps({\"ok\": False, \"message\": \"no results\"})\n\n# after (empty result is not an error)\nreturn json.dumps({\"ok\": True, \"results\": []})","handlingStrategy":"fallback","validationCode":"# treat logical tool failures as data, not crashes: normalize at the boundary\nimport json\n\ndef safe_tool_call(registry, name, params):\n    raw = registry.get_tool(name).run(params)\n    payload = json.loads(raw)\n    if not payload.get(\"ok\"):\n        return None  # signal 'unavailable' instead of raising\n    return payload","typeGuard":null,"tryCatchPattern":"try:\n    result = workflow.run(requirement)\nexcept WorkflowExecutionError as e:\n    if \"未知工具错误\" in str(e):\n        # tool reported ok:false without a message — improve the tool's payload\n        log.warning(\"tool %s failed without message\", stage)\n    raise  # logical failures usually need argument or data fixes, not retries","preventionTips":["Distinguish 'tool failed' (ok:false) from 'tool raised' — handle each differently.","Return ok:true with empty results when 'nothing found' is a normal outcome.","Always include a human-readable message when setting ok:false.","Feed tool error messages back to the model so it can self-correct its arguments."],"tags":["python","tools","llm","workflow"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}