GLTFLoader started behaving differently

Hi. My app distributes the model via CDN in the following format: https://example.com/1234-4567 which returns a GLB object. I am currently migrating from the ThreeJS 1.149.0 to 1.171.0, once I upgraded Three the loader started throwing the following error:

Unexpected token 'Z', "Z2xURgIAAA"... is not valid JSON
SyntaxError: Unexpected token 'Z', "Z2xURgIAAA"... is not valid JSON
    at JSON.parse (<anonymous>)
    at GLTFLoader.parse (http://localhost:3000/static/js/bundle.js:338095:21)
    at Object.onLoad (http://localhost:3000/static/js/bundle.js:338044:15)
    at http://localhost:3000/static/js/bundle.js:319695:39

I assume it happens because it can’t recognize the file type based on the URL and defaults to GLTF instead of GLB. However, I don’t see anything about it in the change log: Migration Guide · mrdoob/three.js Wiki · GitHub

The code for the load looks following:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const DECODER_PATH = '/draco/gltf/';
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath(DECODER_PATH);
dracoLoader.preload();
loader.setDRACOLoader(dracoLoader);

export const loadAndOptimizeGLTFModel = (path: string) => {
  return loader.loadAsync(path);
};


Am I missing something? Is there a way to explicitly specify a file type I am loading if it is not part of the URL?

Did you also update your draco decoder to use the latest that’s been shipped with three? It’s usually kept in public directory and needs manually replacing from node_modules…

Yes, I did update it. I copied it from the node_modules/three/examples/jsm/libs/draco to my public folder.

I noticed that my API returns Content-Type: application/json which may cause the issue, but it wasn’t a problem before.

GLTFLoader attempts to get the resource into an arraybuffer and then to detect whether the resource is JSON or binary (GLB) without reference to the URL. I’m not sure what would cause the problem you’re seeing, but it was not an intentional change.

If you change the Content-Type from your API does that affect the result? I wouldn’t expect so, but a GLB is binary and not JSON, so application/octet-stream would be a better choice.

If you can set a debug breakpoint and see what’s going on, or can provide a demo to reproduce the issue, it would be worth filing a bug. Thanks!

I can’t provide a demo yet, but I tried to debug this thing and it fails here:

Hm, I’m not sure what to make of that. “Z2xU” is neither valid JSON, nor the expected first four bytes of a GLB… so the data coming into this function is not what I’d expect.

I am very sorry for bothering you. It seems something went wrong with the distribution part here. Wrong file is being returned from the API. It is not the ThreeJS issue.

PS: On the positive side, the content type is fixed. :slight_smile:

1 Like

No worries, glad you found the cause! :slight_smile:

1 Like