alibaba/spring-ai-alibaba · error
Feedback result for tool
Error message
Feedback result for tool {} (id={}) is null; waiting for human input. What it means
HumanInTheLoopHook.validateFeedback returns false when a matching ToolFeedback exists for an approval-required tool call but its result is null — feedback was created but no decision recorded, so the hook keeps waiting for human input.
Solutions
- Set a non-null result (approve/reject/edit) on the ToolFeedback before resuming
- Fix UI submission that stores feedback without a result
- Default missing results to reject if policy allows
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/hip/HumanInTheLoopHook.java:247 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/42b325fe8b8f83d8.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/hip/HumanInTheLoopHook.java:247
// 2. For each tool call requiring approval, ensure corresponding feedback exists and its result is non-null
for (AssistantMessage.ToolCall call : toolCallsNeedingApproval) {
InterruptionMetadata.ToolFeedback matchedFeedback = toolFeedbacks.stream()
.filter(tf -> tf.getName().equals(call.name())
// Also validate id if ToolFeedback contains id field
&& call.id().equals(tf.getId()))
.findFirst()
.orElse(null);
if (matchedFeedback == null) {
log.warn("Missing feedback for tool {} (id={}); waiting for human input.",
call.name(), call.id());
return false;
}
// Ensure the feedback result is provided
if (matchedFeedback.getResult() == null) {
log.warn("Feedback result for tool {} (id={}) is null; waiting for human input.",
call.name(), call.id());
return false;
}
}
// 3. Optional: log unexpected or extra feedback entries that do not match any pending approval tool
for (InterruptionMetadata.ToolFeedback tf : toolFeedbacks) {
boolean matched = toolCallsNeedingApproval.stream()
.anyMatch(call -> call.name().equals(tf.getName()) && call.id().equals(tf.getId()));
if (!matched) {
log.warn("Ignoring unexpected tool feedback: name={}, id={}", tf.getName(), tf.getId());
}
}
View on GitHub (pinned to f82da0b50f)