{"record":{"id":"f01934f1815d56fc","repo":"spring-projects/spring-ai","slug":"argumentconsumer-is-required","errorCode":null,"errorMessage":"argumentConsumer is required","messagePattern":"argumentConsumer is required","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-model/src/main/java/org/springframework/ai/tool/augment/AugmentedToolCallbackProvider.java","lineNumber":150,"sourceCode":"\t\t * @param removeExtraArgumentsAfterProcessing true to remove extra arguments\n\t\t * @return this builder\n\t\t */\n\t\tpublic Builder<T> removeExtraArgumentsAfterProcessing(boolean removeExtraArgumentsAfterProcessing) {\n\t\t\tthis.removeExtraArgumentsAfterProcessing = removeExtraArgumentsAfterProcessing;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Builds the {@link AugmentedToolCallbackProvider} instance.\n\t\t * @return the built instance\n\t\t * @throws IllegalStateException if required fields are not set\n\t\t */\n\t\tpublic AugmentedToolCallbackProvider<T> build() {\n\t\t\tif (this.argumentType == null) {\n\t\t\t\tthrow new IllegalStateException(\"argumentType is required\");\n\t\t\t}\n\t\t\tif (this.argumentConsumer == null) {\n\t\t\t\tthrow new IllegalStateException(\"argumentConsumer is required\");\n\t\t\t}\n\n\t\t\tif (this.delegate != null && this.toolObject != null) {\n\t\t\t\tthrow new IllegalStateException(\"Cannot set both delegate and toolObject\");\n\t\t\t}\n\n\t\t\tif (this.delegate == null && this.toolObject == null) {\n\t\t\t\tthrow new IllegalStateException(\"Either delegate or toolObject must be set\");\n\t\t\t}\n\n\t\t\tif (this.toolObject != null) {\n\t\t\t\treturn new AugmentedToolCallbackProvider<>(this.toolObject, this.argumentType, this.argumentConsumer,\n\t\t\t\t\t\tthis.removeExtraArgumentsAfterProcessing);\n\t\t\t}\n\t\t\telse if (this.delegate != null) { // Redundant if condition to please NullAway\n\t\t\t\treturn new AugmentedToolCallbackProvider<>(this.delegate, this.argumentType, this.argumentConsumer,\n\t\t\t\t\t\tthis.removeExtraArgumentsAfterProcessing);\n\t\t\t}","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-model/src/main/java/org/springframework/ai/tool/augment/AugmentedToolCallbackProvider.java#L132-L168","documentation":"AugmentedToolCallbackProvider.Builder.build() validates that an argumentConsumer was registered before constructing the provider. The argumentConsumer supplies the augmented tool arguments (e.g. extra properties injected into the tool input schema) and without it the provider cannot build its AugmentedToolCallback. This is an IllegalStateException thrown to fail fast on an incomplete builder configuration.","triggerScenarios":"Calling AugmentedToolCallbackProvider.builder().argumentType(SomeRecord.class).build() without invoking .argumentConsumer(...) before build().","commonSituations":"Copying builder code and dropping the argumentConsumer line; assuming argumentType alone is sufficient; building the provider programmatically from config where the consumer lambda was optional.","solutions":["Add .argumentConsumer(...) to the builder chain before build(), e.g. builder().argumentType(MyArgs.class).argumentConsumer(args -> {...}).","If no augmentation is needed, use the original ToolCallbackProvider instead of AugmentedToolCallbackProvider.","Wrap builder construction in a shared factory method that always sets both argumentType and argumentConsumer."],"exampleFix":"// before\nvar provider = AugmentedToolCallbackProvider.builder()\n    .argumentType(UserLookupArgs.class)\n    .build();\n// after\nvar provider = AugmentedToolCallbackProvider.builder()\n    .argumentType(UserLookupArgs.class)\n    .argumentConsumer(args -> Map.of(\"userId\", args.userId()))\n    .build();","handlingStrategy":"validation","validationCode":"if (builder == null || argumentType == null || argumentConsumer == null) {\n    throw new IllegalArgumentException(\"AugmentedToolCallbackProvider requires argumentType and argumentConsumer\");\n}","typeGuard":null,"tryCatchPattern":"try { provider = builder.build(); } catch (IllegalStateException e) { log.error(\"Builder misconfigured: {}\", e.getMessage()); throw new ConfigurationException(e); }","preventionTips":["Centralize AugmentedToolCallbackProvider construction in one factory method that sets all required fields.","Never leave a builder chain partially configured; build immediately after configuring."],"tags":["builder-validation","missing-argument","spring-ai"],"backgroundTag":"missing-required-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}