Unable to load gITF model in CesiumJS application


I am working on creating a web map that loads two sets of data from a REST request: one set of addresses and one set of internet service towers. Currently, the towers are being represented by cylinders and the addresses by basic points. As the data loads, a spatial query determines the closest tower to each address and creates a line entity connecting the two features, as you can see in this image:

Now, I am trying to replace one of the towers with a gITF model that I have loaded as an asset in Ion. However, when I load the application, the cylinder that I’m trying to replace simply disappears and the console spits out this error:

TypeError: t.clone is not a function
at new Td (Cesium.js:5843:78771)
at xo.fromGltfAsync (Cesium.js:7175:44240)
at EXe (Cesium.js:8325:266870)
at om.update (Cesium.js:8325:268047)
at Sf.update (Cesium.js:8325:308158)
at Ri._onTick (Cesium.js:14476:112605)
at nw.raiseEvent (Cesium.js:95:1282)
at G9.tick (Cesium.js:8325:43587)
at OT.render (Cesium.js:14432:1612)
at n (Cesium.js:14430:8645)

I am very new to Cesium, so this error means nothing to me. Any guidance would be greatly appreciated! Here is a snippet of my code as well:

Hi there,

Would it be possible to provide the glTF model for troubleshooting?

It may also help to run the model through the glTF validator to ensure it’s valid data.

Hi Gabby,

Thank you for your response! I have the model uploaded in Cesium Ion, where I converted it into a glTF format. The original file was a .zip folder containing a .dae and .jpg texture file. Could this be causing the issue?


Let’s take a look. Would you be able to provide the asset ID?

For sure! - 2232397

Thanks @ahillier!

I grabbed the glb that was generated by ion. The model seems to be loading fine using the following code:

 const position = Cesium.Cartesian3.fromDegrees(
  const heading = Cesium.Math.toRadians(135);
  const pitch = 0;
  const roll = 0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  const orientation = Cesium.Transforms.headingPitchRollQuaternion(

  const entity = viewer.entities.add({
    name: "model.glb",
    position: position,
    orientation: orientation,
    model: {
      uri: "//localhost:8080/model.glb",
      minimumPixelSize: 20,

What is the value of towerModel in your code?

I’ve since adjusted my code, but I think in the example it was simply the reference to the Ion asset:

const towerModel = Cesium.IonResource.fromAssetId(2232397);

IonResource.fromAssetId returns a Promise to a Resource, rather than a Resource directly.

Try const towerModel = await Cesium.IonResource.fromAssetId(2232397);.

Note the await keyword.

That seems to have worked, however the model is not loading in the correct position, even though when I click on the model, the selection indicator is in the correct place (where the tower should be).


Is the model underground or somewhere else entirely? Did you do any geolocation in Cesium ion? Also how are you setting the position in CesiumJS?

The model is being loaded away from the point and floating above the terrain. It’s kind of hard to see in the image I shared, but it’s just to the left of the infobox.

I’m not doing any geolocation in Ion. I am using the data from my fetch request to create an array of positions for each of the towers:

var towerLocations =
for (let i = 0; i < towers.length; i++) {
let location = new Cesium.Cartesian3.fromDegrees(towers[i].location.value.coordinates[0], towers[i].location.value.coordinates[1], towers[i].antHeight.value);

Then I am using towerPositions[i] for the ‘position’ property of the model.

Are you setting the orientation property at all?

  const heading = Cesium.Math.toRadians(0);
  const pitch = 0;
  const roll = 0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  orientation: Cesium.Transforms.headingPitchRollQuaternion(

I wasn’t seeing this behavior in my example above, so I wonder what else is different.

I wasn’t setting the orientation property before, however I just implemented the snippet you provided and the same issue is happening.

Does the collada (.dae) file contain any other content?

This could happen because the bounding volume calculated for the model is very large.

There isn’t anything else in the collada file (to my knowledge). I uploaded the model as a 3D tileset and when I attached the lines to the centre of the bounding sphere for the model, they were relatively close to the tower itself, so I don’t think that is the issue.

We have had some issues with some of the model files so our company is going to re-do some of the scans and re-export them. Hopefully this will solve some of the issues, but if not, I will check back in when we have those files! :slight_smile:

Another thought:

I have this same model loaded as a 3D tileset in Cesium Ion - could I potentially add the tileset instead of the model with the position that was set within Ion? I would like to add it as an entity if possible, so I can add attributes to the infobox popup!

@ahillier Yes! Go ahead and use the 3D tileset. The API is a bit different, but I would expect the location to be accurate as you’ve configured it in ion.

That worked perfectly! Thank you for your help! :slight_smile:

@Gabby_Getz back again! :slight_smile: so unfortunately, I am now having issues loading my tilesets from Ion. Everything was working fine on Friday, and when I logged in after the weekend my tower models were no longer loading! Here is a snippet of my code:

I have tried various methods for the ‘uri’ property for the tileset and I keep getting a 401 error (invalid credentials/invalid access token).

The funny thing is that my custom terrain layer is loading without an issue, so I’m not sure what the problem is. I’ve refreshed the access token multiple times (since I am using v 1.108, not 1.109) so I’m pretty stumped.

Any insight on this issue would be great! Thanks :slight_smile:

I also get this error a bunch of times in the console with the current code. The viewer zooms to where the tileset should be, but nothing is visible/clickable.