spring-projects/spring-ai · error · RuntimeException

Failed to parse tool input schema:

Error message

Failed to parse tool input schema: 

What it means

AnthropicChatModel converts a Spring AI ToolDefinition's inputSchema JSON string into the Anthropic SDK's InputSchema builder. If parsing/converting that JSON schema fails, the model rethrows a RuntimeException 'Failed to parse tool input schema: <schema>' with the cause, so the malformed schema is visible in the message.

Source

Thrown at models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java:1308

				.properties(propertiesBuilder.build());

			// Add required fields if present
			Object requiredObj = schemaMap.get("required");
			if (requiredObj instanceof java.util.List) {
				java.util.List<String> required = (java.util.List<String>) requiredObj;
				for (String req : required) {
					inputSchemaBuilder.addRequired(req);
				}
			}

			return Tool.builder()
				.name(toolDefinition.name())
				.description(toolDefinition.description())
				.inputSchema(inputSchemaBuilder.build())
				.build();
		}
		catch (Exception e) {
			throw new RuntimeException("Failed to parse tool input schema: " + toolDefinition.inputSchema(), e);
		}
	}

	/**
	 * Converts a Spring AI {@link AnthropicWebSearchTool} to the Anthropic SDK's
	 * {@link WebSearchTool20260209}.
	 * @param webSearchTool the web search configuration
	 * @return the SDK web search tool
	 */
	private WebSearchTool20260209 toSdkWebSearchTool(AnthropicWebSearchTool webSearchTool) {
		WebSearchTool20260209.Builder sdkBuilder = WebSearchTool20260209.builder();

		if (webSearchTool.getAllowedDomains() != null) {
			sdkBuilder.allowedDomains(webSearchTool.getAllowedDomains());
		}
		if (webSearchTool.getBlockedDomains() != null) {
			sdkBuilder.blockedDomains(webSearchTool.getBlockedDomains());
		}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Read the schema text in the exception message and validate it with a JSON/JSON-Schema validator
  2. Build the schema with JsonSchemaGenerator or a typed Map serialized via Jackson instead of hand-written strings
  3. Verify the JSON uses proper types ('type' is a string, 'properties' is an object)
  4. Align Spring AI and JSON library versions on the classpath

Example fix

// before
ToolDefinition.builder().name("t").inputSchema("{type: 'object'}").build(); // invalid JSON
// after
ToolDefinition.builder().name("t")
    .inputSchema("{\"type\":\"object\",\"properties\":{}}").build();
Defensive patterns

Strategy: validation

Validate before calling

try (Parser p = new JsonParser()) { p.parse(toolDefinition.inputSchema()); } // reject invalid JSON before registering

Type guard

boolean isValidJson(String s) { try { new ObjectMapper().readTree(s); return true; } catch (Exception e) { return false; } }

Try / catch

try { schema = buildAnthropicSchema(toolDefinition); }
catch (RuntimeException e) { throw new IllegalStateException("Bad inputSchema for tool " + toolDefinition.name(), e); }

Prevention

When it happens

Trigger: Registering a tool whose inputSchema() string is not valid JSON, is empty, or has a structure the converter rejects (wrong JSON types inside the schema) when the request is built.

Common situations: Hand-written tool schema strings with typos; schema built via string concatenation; a ToolDefinition from another module producing a non-JSON schema; classpath version mismatch of JSON libraries.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/7c0729308f36e549. Report an issue: GitHub.