{"record":{"id":"6be4266666a6ec25","repo":"alibaba/spring-ai-alibaba","slug":"build-tool-result-error","errorCode":"BUILD_TOOL_RESULT_ERROR","errorMessage":"BUILD_TOOL_RESULT_ERROR","messagePattern":"BUILD_TOOL_RESULT_ERROR","errorType":"error_code","errorClass":"BizException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/ToolExecutionServiceImpl.java","lineNumber":291,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Builds the output map from the API response.\n\t * @param respJSONObj The JSON response object\n\t * @param outputParams The expected output parameters\n\t * @return Map containing the processed output values\n\t */\n\tpublic Map<String, Object> buildOutputs(Map<String, Object> respJSONObj, List<ApiParameter> outputParams) {\n\t\tMap<String, Object> outputs = new HashMap<String, Object>();\n\n\t\ttry {\n\t\t\toutputs = respJSONObj;\n\t\t\t// constructOutputs(respJSONObj, outputs, outputParams);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new BizException(ErrorCode.BUILD_TOOL_RESULT_ERROR.toError(), e);\n\t\t}\n\n\t\treturn outputs;\n\t}\n\n\t/**\n\t * Recursively constructs output objects based on parameter types. Handles different\n\t * data types including objects and arrays.\n\t * @param sourceObject The source data object\n\t * @param targetObj The target object to populate\n\t * @param outputParams The output parameter definitions\n\t */\n\tprivate void constructOutputs(Map<String, Object> sourceObject, Map<String, Object> targetObj,\n\t\t\tList<ApiParameter> outputParams) {\n\t\tif (CollectionUtils.isEmpty(outputParams)) {\n\t\t\treturn;\n\t\t}\n","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/ToolExecutionServiceImpl.java#L273-L309","documentation":"BUILD_TOOL_RESULT_ERROR is thrown by buildOutputs in ToolExecutionServiceImpl when constructing the tool's output map from the parsed response JSON object fails. The try block assigns respJSONObj to outputs (the per-field constructOutputs step is currently commented out), so in practice this fires only on truly unexpected runtime failures during output assembly.","triggerScenarios":"buildOutputs receiving a respJSONObj that causes a RuntimeException during assignment/output-map construction; any future re-enabled constructOutputs logic failing on unexpected response shapes.","commonSituations":"Remote tool API returning null or an unexpected structure that downstream output building cannot handle; regression after modifying buildOutputs/constructOutputs; memory/runtime errors during large response handling.","solutions":["Inspect the cause attached to the BizException for the real failure.","Log and verify the raw response JSON the remote tool returned before output building.","If you modified constructOutputs, review it for null/shape assumptions and re-run.","Check the remote tool's API contract and normalize its response before calling buildOutputs."],"exampleFix":"// before\nObject outputs = buildOutputs(respJSONObj, outputParams); // throws BUILD_TOOL_RESULT_ERROR\n// after\ntry {\n    Object outputs = buildOutputs(respJSONObj, outputParams);\n} catch (BizException e) {\n    log.warn(\"Failed to build tool result\", e.getCause());\n    Object outputs = Collections.emptyMap(); // graceful degradation\n}","handlingStrategy":"try-catch","validationCode":"if (respJSONObj == null) { log.warn(\"Tool returned null response; skipping output build\"); return Collections.emptyMap(); }","typeGuard":"if (!(resp instanceof JSONObject)) { throw new IllegalStateException(\"Unexpected response type: \" + resp.getClass()); }","tryCatchPattern":"try { outputs = buildOutputs(resp, outputParams); } catch (BizException e) { log.error(\"BUILD_TOOL_RESULT_ERROR\", e.getCause()); outputs = Collections.emptyMap(); }","preventionTips":["Log raw remote responses to spot shape changes early","Null-check parsed response before output building","Keep constructOutputs defensive against missing fields","Add contract tests against recorded real responses"],"tags":["tool-execution","response-processing","internal-error","admin-server"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}