{"record":{"id":"3753ffcb26235e38","repo":"alibaba/spring-ai-alibaba","slug":"missing-feedback-for-tool-id-waiting-for","errorCode":null,"errorMessage":"Missing feedback for tool {} (id={}); waiting for human input.","messagePattern":"Missing feedback for tool (.+?) \\(id=(.+?)\\); waiting for human input\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/hip/HumanInTheLoopHook.java","lineNumber":240,"sourceCode":"                .filter(tc -> approvalOn.containsKey(tc.name()))\n                .toList();\n\n        // If no tool calls in this step require human approval, validation is trivially satisfied\n        if (toolCallsNeedingApproval.isEmpty()) {\n            return true;\n        }\n\n        // 2. For each tool call requiring approval, ensure corresponding feedback exists and its result is non-null\n        for (AssistantMessage.ToolCall call : toolCallsNeedingApproval) {\n            InterruptionMetadata.ToolFeedback matchedFeedback = toolFeedbacks.stream()\n                    .filter(tf -> tf.getName().equals(call.name())\n                            // Also validate id if ToolFeedback contains id field\n                            && call.id().equals(tf.getId()))\n                    .findFirst()\n                    .orElse(null);\n\n            if (matchedFeedback == null) {\n                log.warn(\"Missing feedback for tool {} (id={}); waiting for human input.\",\n                        call.name(), call.id());\n                return false;\n            }\n\n            // Ensure the feedback result is provided\n            if (matchedFeedback.getResult() == null) {\n                log.warn(\"Feedback result for tool {} (id={}) is null; waiting for human input.\",\n                        call.name(), call.id());\n                return false;\n            }\n        }\n\n        // 3. Optional: log unexpected or extra feedback entries that do not match any pending approval tool\n        for (InterruptionMetadata.ToolFeedback tf : toolFeedbacks) {\n            boolean matched = toolCallsNeedingApproval.stream()\n                    .anyMatch(call -> call.name().equals(tf.getName()) && call.id().equals(tf.getId()));\n            if (!matched) {\n                log.warn(\"Ignoring unexpected tool feedback: name={}, id={}\", tf.getName(), tf.getId());","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/hip/HumanInTheLoopHook.java#L222-L258","documentation":"HumanInTheLoopHook.validateFeedback returns false (keeping the graph interrupted) when a tool call that requires approval has no matching ToolFeedback entry in InterruptionMetadata — human input for that tool call is still missing.","triggerScenarios":"Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/hip/HumanInTheLoopHook.java:240 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Provide feedback (approve/reject/edit) for every approval-required tool call before resuming","Match feedback by both tool name and call id","Return validation errors to the UI listing pending tool calls"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}