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

  1. Copy bytes into a ByteBuffer dst; if you need them as floats, get a view: byteDst.asFloatBuffer().put(...) or read via asFloatBuffer().
  2. If your data is already float[], use copy(float[], int, Buffer, int) which accepts a FloatBuffer dst.
  3. 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

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


AI-assisted analysis of libgdx/libgdx@97f4086187 (2026-08-14). Data as JSON: /api/errors/b106cdbe62afec71. Report an issue: GitHub.