alibaba/spring-ai-alibaba · warning · BizException
INVALID_PARAMS
INVALID_PARAMS
Error message
can not find published component: + code
What it means
HumanInTheLoopHook.validateFeedback() requires that every tool call which needed approval has a matching ToolFeedback entry (matched by tool name and call id). If a pending call has no feedback, validation returns false, the interrupt stays active, and this warning explains which tool/id is still awaiting human input.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/manager/AppComponentManager.java:266
}
String config = appComponent.getConfig();
if (config != null) {
return JsonUtils.fromJson(config, AppComponentConfig.class);
}
return null;
}
public HashMap<String, ToolCallSchema> getToolCallSchema(List<String> codes) {
if (CollectionUtils.isEmpty(codes)) {
return null;
}
HashMap<String, ToolCallSchema> toolCallSchemas = new HashMap<>();
for (String code : codes) {
AppComponent appComponent = appComponentService.getAppComponentByCode(code,
AppComponentStatusEnum.Published.getCode());
if (appComponent == null) {
throw new BizException(ErrorCode.INVALID_PARAMS.toError("component_code",
"can not find published component: " + code));
}
AppComponentConfig appComponentConfig = getAppComponentInputConfig(appComponent);
ToolCallSchema toolCallSchema = new ToolCallSchema();
toolCallSchema.setName(appComponent.getName());
toolCallSchema.setDescription(appComponent.getDescription());
AppComponentConfig.Input input = appComponentConfig.getInput();
InputSchema inputSchema = new InputSchema();
toolCallSchema.setInputSchema(inputSchema);
Map<String, Object> properties = new HashMap<>();
List<String> required = new ArrayList<>();
inputSchema.setProperties(properties);
inputSchema.setRequired(required);
for (AppComponentConfig.UserParams userParam : input.getUserParams()) {
if (CollectionUtils.isNotEmpty(userParam.getParams())) {
for (AppComponentConfig.Params param : userParam.getParams()) {
if (Objects.equals(param.getSource(), APIPluginValueSourceEnum.BIZ.getCode())) {View on GitHub (pinned to f82da0b50f)
Solutions
- Provide a ToolFeedback for every pending tool call id in the interrupt metadata
- Copy name AND id exactly from the AssistantMessage's tool calls when building feedback
- Inspect the persisted InterruptionMetadata to list pending call ids and validate the client payload against it
- Regenerate the interrupt (new ids) if the client cached stale ids from a previous run
Example fix
// before
List<ToolFeedback> feedback = List.of(new ToolFeedback("search", "approved")); // id missing/stale
// after
List<ToolFeedback> feedback = pendingCalls.stream()
.map(call -> new ToolFeedback(call.name(), call.id(), "approved"))
.toList(); // one feedback per pending call id Defensive patterns
Strategy: validation
Validate before calling
Set<String> pendingIds = toolCallsNeedingApproval.stream().map(AssistantMessage.ToolCall::id).collect(java.util.stream.Collectors.toSet());
Set<String> answered = toolFeedbacks.stream().map(InterruptionMetadata.ToolFeedback::getId).collect(java.util.stream.Collectors.toSet());
if (!pendingIds.equals(answered)) throw new IllegalArgumentException("Feedback must cover every pending tool id: " + pendingIds); Type guard
boolean coversAllPending(List<ToolCall> pending, List<ToolFeedback> fb) {
return pending.stream().allMatch(c -> fb.stream().anyMatch(f -> c.id().equals(f.getId()) && c.name().equals(f.getName())));
} Prevention
- Always echo both name and id from the interrupt metadata into feedback
- Render all pending approvals in the UI so users answer every one
- Regenerate interrupt metadata instead of reusing ids across runs
When it happens
Trigger: interrupt() is called to decide whether to resume; one of toolCallsNeedingApproval has no entry in the provided InterruptionMetadata.ToolFeedback list whose getName()/getId() equal the call's name()/id().
Common situations: UI only submitting answers for some of several pending approval requests; id mismatch because the client echoed stale ids from an older interrupt; feedback built by hand without copying call.id(); multiple tool calls in one AssistantMessage but feedback given for one.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- user define param: + userParamParam.getField() + is empty
- failed to create dir: + saveFile.getParentFile()
- extra tool param should be map
- Human feedback metadata must be of type InterruptionMetadata
- Failed to check interruptAfter hook for streaming node
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/0128842040aafea8.
Report an issue: GitHub.