alibaba/spring-ai-alibaba · error · IllegalArgumentException

bytes cannot be empty

Error message

bytes cannot be empty

What it means

StateSerializer.dataFromBytes performs the same validation as Serializer.bytesToObject: null bytes throw NullPointerException, and a zero-length array throws IllegalArgumentException("bytes cannot be empty"), because ObjectInputStream cannot read state data from an empty stream.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/serializer/StateSerializer.java:80

	public abstract void writeData(Map<String, Object> data, ObjectOutput out) throws IOException;

	public abstract Map<String, Object> readData(ObjectInput in) throws IOException, ClassNotFoundException;

	public final byte[] dataToBytes(Map<String, Object> data) throws IOException {
		Objects.requireNonNull(data, "object cannot be null");
		try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
			ObjectOutputStream oas = new ObjectOutputStream(stream);
			writeData(data, oas);
			oas.flush();
			return stream.toByteArray();
		}
	}

	public final Map<String, Object> dataFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
		Objects.requireNonNull(bytes, "bytes cannot be null");
		if (bytes.length == 0) {
			throw new IllegalArgumentException("bytes cannot be empty");
		}
		try (ByteArrayInputStream stream = new ByteArrayInputStream(bytes)) {
			ObjectInputStream ois = new ObjectInputStream(stream);
			return readData(ois);
		}
	}

}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Validate the byte array (length > 0) before deserializing state
  2. Re-run the checkpoint save path and confirm bytes are non-empty on write
  3. Purge corrupt/empty checkpoints so the graph starts from a fresh state
  4. Add a round-trip unit test for your StateSerializer to catch empty-payload writes

Example fix

// before
Map<String,Object> state = serializer.dataFromBytes(raw);
// after
Map<String,Object> state = (raw == null || raw.length == 0)
    ? Map.of()
    : serializer.dataFromBytes(raw);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.length == 0) {
    return Map.of(); // or re-initialize default graph state
}

Type guard

boolean hasStateBytes(byte[] b) {
    return b != null && b.length > 0;
}

Try / catch

try {
    return serializer.dataFromBytes(bytes);
} catch (IllegalArgumentException e) {
    if ("bytes cannot be empty".equals(e.getMessage())) {
        return new HashMap<>(); // start from empty state
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling dataFromBytes (or deserialized()) with an empty byte[] produced by a failed/empty save — e.g. an empty checkpoint blob loaded from Redis/PostgreSQL/file, or a serialization step that silently wrote nothing.

Common situations: Empty Redis keys storing empty arrays; interrupted checkpoint writes; schema/migration issues leaving state columns empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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