alibaba/spring-ai-alibaba · error · IllegalStateException

Failed to build JSON-RPC payload

Error message

Failed to build JSON-RPC payload

What it means

Building the JSON-RPC message/send request body uses Jackson ObjectMapper.writeValueAsString; if serialization fails (unserializable value in state-derived params), the method wraps it in this IllegalStateException. Essentially a defensive wrap around JSON generation of the A2A request.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/a2a/A2aNodeActionWithConfig.java:709

		params.put("message", message);

		Map<String, Object> metadata = new HashMap<>();
		config.threadId().ifPresent(threadId -> metadata.put("threadId", threadId));
		// FIXME, the key 'userId' should be configurable
		config.metadata("userId").ifPresent(userId -> metadata.put("userId", userId));
		params.put("metadata", metadata);

		Map<String, Object> root = new HashMap<>();
		root.put("id", id);
		root.put("jsonrpc", "2.0");
		root.put("method", "message/send");
		root.put("params", params);

		try {
			return objectMapper.writeValueAsString(root);
		}
		catch (Exception e) {
			throw new IllegalStateException("Failed to build JSON-RPC payload", e);
		}
	}

	/**
	 * Build the JSON-RPC streaming request payload (method: message/stream).
	 * @param state Parent state
	 * @return JSON string payload for streaming
	 */
	private String buildSendStreamingMessageRequest(OverAllState state, RunnableConfig config) {
		Object textValue = getEffectiveInstruction(state);
		String text = String.valueOf(textValue);

		String id = UUID.randomUUID().toString();
		String messageId = UUID.randomUUID().toString().replace("-", "");

		Map<String, Object> part = Map.of("kind", "text", "text", text);

		Map<String, Object> message = new HashMap<>();

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Ensure values read from state are JSON-friendly (String, Number, Map, List) before they go into params
  2. Register needed Jackson modules (e.g. JavaTimeModule) or configure the ObjectMapper correctly
  3. Log/catch the cause (the exception carries the underlying JsonProcessingException) and fix the offending field

Example fix

// before
state.put("attachment", new FileInputStream(file)); // unserializable
// after
state.put("attachment", Files.readString(file.toPath()));
Defensive patterns

Strategy: validation

Validate before calling

// ensure state values are JSON-friendly before building the request
boolean serializable(Object o) {
    try { new ObjectMapper().writeValueAsString(o); return true; }
    catch (Exception e) { return false; }
}

Try / catch

try {
    String payload = action.buildPayload(state);
} catch (IllegalStateException e) {
    // inspect cause (JsonProcessingException) and fix the unserializable value
}

Prevention

When it happens

Trigger: getEffectiveInstruction/rendered template or state values placed into the params map cannot be serialized by Jackson (e.g. an object with no properties, infinite recursion, or an unsupported type like InputStream).

Common situations: Passing Java objects (streams, custom classes without getters) into agent state that end up rendered into the payload; template rendering producing an object Jackson can't handle; misconfigured ObjectMapper modules.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/a8d9bc4a2f1df087. Report an issue: GitHub.