libgdx/libgdx · error · GdxRuntimeException
dst must be a ByteBuffer
Error message
dst must be a ByteBuffer
What it means
BufferUtils.copy(byte[] src, int srcOffset, Buffer dst, int numElements) requires dst to be a ByteBuffer because byte copies go straight through ByteBuffer.put — there is no typed view to convert through. Any other Buffer subclass (IntBuffer, FloatBuffer, ...) fails the instanceof check and throws. The overloads for short/char/int/long/double accept ByteBuffer or their typed buffer, but the byte variant is ByteBuffer-only.
Source
Thrown at backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/emu/com/badlogic/gdx/utils/BufferUtils.java:70
floatBuffer.put(src, offset, numFloats);
dst.position(0);
if (dst instanceof ByteBuffer)
dst.limit(numFloats << 2);
else
dst.limit(numFloats);
}
/** Copies the contents of src to dst, starting from src[srcOffset], copying numElements elements. The {@link Buffer}
* instance's {@link Buffer#position()} is used to define the offset into the Buffer itself. The position will stay the same,
* the limit will be set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order. No error
* checking is performed</b>.
*
* @param src the source array.
* @param srcOffset the offset into the source array.
* @param dst the destination Buffer, its position is used as an offset.
* @param numElements the number of elements to copy. */
public static void copy (byte[] src, int srcOffset, Buffer dst, int numElements) {
if (!(dst instanceof ByteBuffer)) throw new GdxRuntimeException("dst must be a ByteBuffer");
ByteBuffer byteBuffer = (ByteBuffer)dst;
int oldPosition = byteBuffer.position();
byteBuffer.limit(oldPosition + numElements);
byteBuffer.put(src, srcOffset, numElements);
byteBuffer.position(oldPosition);
}
/** Copies the contents of src to dst, starting from src[srcOffset], copying numElements elements. The {@link Buffer}
* instance's {@link Buffer#position()} is used to define the offset into the Buffer itself. The position will stay the same,
* the limit will be set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order. No error
* checking is performed</b>.
*
* @param src the source array.
* @param srcOffset the offset into the source array.
* @param dst the destination Buffer, its position is used as an offset.
* @param numElements the number of elements to copy. */
public static void copy (short[] src, int srcOffset, Buffer dst, int numElements) {View on GitHub (pinned to 97f4086187)
Solutions
- Copy bytes into a ByteBuffer dst; if you need them as floats, get a view: byteDst.asFloatBuffer().put(...) or read via asFloatBuffer().
- If your data is already float[], use copy(float[], int, Buffer, int) which accepts a FloatBuffer dst.
- Allocate dst with BufferUtils.newByteBuffer(...) and convert after the copy.
Example fix
// before FloatBuffer fb = BufferUtils.newFloatBuffer(bytes.length / 4); BufferUtils.copy(bytes, 0, fb, bytes.length); // throws: dst must be a ByteBuffer // after ByteBuffer bb = BufferUtils.newByteBuffer(bytes.length); BufferUtils.copy(bytes, 0, bb, bytes.length); bb.position(0); FloatBuffer fb = bb.asFloatBuffer();
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(dst instanceof ByteBuffer)) {
throw new IllegalArgumentException("dst must be ByteBuffer for byte[] copy");
}
BufferUtils.copy(bytes, 0, dst, bytes.length); Type guard
boolean acceptsByteArray(Buffer b) { return b instanceof ByteBuffer; } Prevention
- Reserve ByteBuffer for byte[] copies; use typed views afterwards.
- Wrap BufferUtils.copy in project helpers that fix src/dst type pairs.
When it happens
Trigger: Passing a FloatBuffer/IntBuffer as dst when copying a byte[]; generic buffer-fill helper code that treats all copy overloads uniformly; copying raw vertex bytes into a mesh's typed FloatBuffer.
Common situations: Writing serialization/network code that unpacks bytes into typed buffers via copy() instead of view buffers; refactoring code from copyVBO/other BufferUtils APIs where ByteBuffer was always the receiver; porting desktop NIO code to the GWT emulated BufferUtils with mismatched buffer types.
Related errors
- Only ByteBuffer is currently supported
- dst must be a ByteBuffer or ShortBuffer
- dst must be a ByteBuffer or CharBuffer
- dst must be a ByteBuffer or IntBuffer
- dst must be a ByteBuffer or LongBuffer
AI-assisted analysis of libgdx/libgdx@97f4086187 (2026-08-14).
Data as JSON: /api/errors/b106cdbe62afec71.
Report an issue: GitHub.