alibaba/spring-ai-alibaba · error · IllegalStateException

Failed to build JSON-RPC streaming payload

Error message

Failed to build JSON-RPC streaming payload

What it means

Same serialization guard as the non-streaming payload builder, but for the message/stream (SSE) JSON-RPC request. writeValueAsString failure on the streaming request root object raises this IllegalStateException with the streaming-specific message.

Source

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

		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/stream");
		root.put("params", params);

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

	private String getEffectiveInstruction(OverAllState state) {
		if (StringUtils.hasLength(this.instruction)) {
			PromptTemplate template = PromptTemplate.builder().template(this.instruction).build();
			return template.render(state.data());
		} else if (!shareState || (shareState && state.value("messages").isEmpty())) {
			throw new IllegalStateException("Instruction is empty and shareState is false");
		}
		return "";
	}

	/**
	 * Send the request to the remote A2A server and return the non-streaming response.
	 * @param agentCard Agent card (source for server URL/metadata)
	 * @param requestPayload JSON string payload built by buildSendMessageRequest
	 * @return Response body as string

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Use only JSON-serializable values in the fields that feed the streaming payload
  2. Inspect the wrapped cause exception for the exact serialization failure and fix that type
  3. Ensure ObjectMapper has required modules registered

Example fix

// before
root.put("params", Map.of("ctx", someComplexObject));
// after
root.put("params", Map.of("ctx", someComplexObject.toString()));
Defensive patterns

Strategy: validation

Validate before calling

// serialize a dry-run payload before sending
try { objectMapper.writeValueAsString(root); } catch (Exception e) { /* fix types first */ }

Try / catch

try {
    String payload = action.buildStreamingPayload(state);
} catch (IllegalStateException e) {
    // log cause; fix unserializable param values
}

Prevention

When it happens

Trigger: Building the message/stream payload when a value contributed to params (rendered instruction, message text, context/state-derived fields) cannot be serialized by Jackson.

Common situations: Non-serializable state values streamed requests share with non-streaming; custom state objects without getters; missing Jackson module for a type used in streaming params.

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/b947a26790476414. Report an issue: GitHub.