alibaba/spring-ai-alibaba · error · IllegalArgumentException

bytes cannot be empty

Error message

bytes cannot be empty

What it means

Serializer.bytesToObject validates the input byte array before deserializing: it throws NullPointerException for null bytes and IllegalArgumentException("bytes cannot be empty") for a zero-length array, since ObjectInputStream requires at least a stream header to read from.

Source

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

	default String contentType() {
		return "application/octet-stream";
	}

	default byte[] objectToBytes(T object) throws IOException {
		Objects.requireNonNull(object, "object cannot be null");
		try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
			ObjectOutputStream oas = new ObjectOutputStream(stream);
			write(object, oas);
			oas.flush();
			return stream.toByteArray();
		}
	}

	default T bytesToObject(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 read(ois);
		}
	}

	@Deprecated(forRemoval = true)
	default byte[] writeObject(T object) throws IOException {
		return objectToBytes(object);
	}

	@Deprecated(forRemoval = true)
	default T readObject(byte[] bytes) throws IOException, ClassNotFoundException {
		return bytesToObject(bytes);
	}

	default T cloneObject(T object) throws IOException, ClassNotFoundException {

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Check byte[] != null && bytes.length > 0 before calling bytesToObject
  2. Fix the persistence layer to write a valid serialized payload instead of an empty array
  3. Delete/repair the corrupt checkpoint record so the graph can re-initialize state
  4. Verify serialization on write (serialize-then-deserialize round-trip) to catch empty payloads early

Example fix

// before
T obj = serializer.bytesToObject(bytes);
// after
if (bytes == null || bytes.length == 0) {
    return defaultState();
}
T obj = serializer.bytesToObject(bytes);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.length == 0) {
    throw new IllegalArgumentException("cannot deserialize empty checkpoint payload");
}

Type guard

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

Try / catch

try {
    return serializer.bytesToObject(bytes);
} catch (IllegalArgumentException e) {
    if ("bytes cannot be empty".equals(e.getMessage())) {
        return defaultState(); // rebuild instead of failing
    }
    throw e;
} catch (IOException | ClassNotFoundException e) {
    throw new IllegalStateException("corrupt payload", e);
}

Prevention

When it happens

Trigger: Calling bytesToObject (directly or via readObject) with an empty byte[] — e.g. a persisted snapshot/checkpoint that was saved as an empty array, a truncated DB/blob column, or code that serializes to bytes but stores nothing.

Common situations: Corrupt or empty checkpoint rows in PostgreSQL/Redis/file persistence; migration writing default empty blobs; passing a newly-allocated but never-filled buffer.

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