R3F GLTF Not Loading on AWS Amplify

I’m using webpack, distributing using AWS amplify.
Everything is working perfectly locally but as soon as it’s pushed to the server then I get an error that the GLTF file cannot be loaded, stating a different name than what the actual gltf file is called, is it renamed at some point during the loading process?

I figure most of these problems are attributed to me not having a public folder as amplify doesn’t support that, but the path for all the assets are correct and all of my other assets (pngs, svgs) that i’m animating using three.js are loading and working just fine, except the GLTF file.

Error message:

Uncaught Could not load /12aa89ff0220050381c1e9d62d3d9c14.gltf: Unexpected token < in JSON at position 0
react-reconciler.development.js:11782 The above error occurred in the <MercedesF1> component:

    at MercedesF1 (https://testing-gpracing.dk7zoarrp1yn8.amplifyapp.com/app.3fcb00d6.js:113650:62)
    at Suspense
    at group
    at Rig (https://testing-gpracing.dk7zoarrp1yn8.amplifyapp.com/app.3fcb00d6.js:60253:23)
    at Suspense
    at Suspense
    at ErrorBoundary (https://testing-gpracing.dk7zoarrp1yn8.amplifyapp.com/app.3fcb00d6.js:119466:5)
    at Provider (https://testing-gpracing.dk7zoarrp1yn8.amplifyapp.com/app.3fcb00d6.js:119745:3)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

The component that it is referencing:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/
import * as THREE from 'three';
import React, { useRef } from 'react';
import { useGLTF } from '@react-three/drei';
import { GLTF } from 'three-stdlib';
import mercedes from '../../assets/f1.gltf';

// file is being resolved by loader and a new url is returned.
import { useLoader } from '@react-three/fiber';
// import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

// const loader = new GLTFLoader();

type GLTFResult = GLTF & {
  nodes: {
    W05_me_body_SUB0_1: THREE.Mesh;
    W05_me_body_SUB0_2: THREE.Mesh;
    W05_me_body_SUB0_3: THREE.Mesh;
    W05_me_body_SUB0_4: THREE.Mesh;
    W05_me_body_SUB0_5: THREE.Mesh;
    W05_me_body_SUB0_6: THREE.Mesh;
    W05_me_body_SUB0_7: THREE.Mesh;
  };
  materials: {
    body: THREE.MeshStandardMaterial;
    mirror: THREE.MeshStandardMaterial;
    generic: THREE.MeshStandardMaterial;
    rim: THREE.MeshStandardMaterial;
    tyre: THREE.MeshStandardMaterial;
    glass: THREE.MeshStandardMaterial;
    Steer: THREE.MeshStandardMaterial;
  };
};

export default function MercedesF1({
  ...props
}: JSX.IntrinsicElements['group']) {
  const group = useRef<THREE.Group>();
  // const { nodes, materials } = useGLTF(mercedes) as GLTFResult;

  const { nodes, materials } = useLoader(GLTFLoader, mercedes);

  return (
    // <primitive object={scene} />
    <group ref={group} {...props} dispose={null}>
      <group rotation={[Math.PI / 2, 0, 0]}>
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_1.geometry}
          material={materials.body}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_2.geometry}
          material={materials.mirror}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_3.geometry}
          material={materials.generic}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_4.geometry}
          material={materials.rim}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_5.geometry}
          material={materials.tyre}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_6.geometry}
          material={materials.glass}
        />
        <mesh
          castShadow
          receiveShadow
          //@ts-ignore
          geometry={nodes.W05_me_body_SUB0_7.geometry}
          material={materials.Steer}
        />
      </group>
    </group>
  );
}

// const loadter = useGLTF.preload('../');

I’ve tried both useGLTF and useLoader in hopes that there is a difference in output but I get the same error both times. I’m completely stuck with this one. The gltf file is in my assets folder inside src, it’s copied across to the server as I can see it in the file directory. Not sure why the name is being changed from the f1.gltf to the random hash name given in the error, is it dumping this into a public folder that doesn’t exist?

Appreciate any help

I have the same bug :frowning:

wrong path, missing binares/texture. the error is a 404 error “file could not be loaded” which the GLTFparser tries to parse as a GLTF, thereby running into the < in JSON at position 0 thing. it happens if you guide GLTFLoader towards an url that it won’t be able to resolve.

in order to avoid issues, better use glb instead of gltf, they already include all assets and are compressed. i would stick models into /public and load them as “/model.glb”.

when you import a model it can in theory reside within /src, the bundler will now include it in the production build under /dist. it will not use the original name, it uses a hash signature in order to control caching the files.

there is no apparent error in your code, so i assume that the bundler lifts the gltf into /dist but not the textures and binaries that it refers to, and really there is no way it could or should. it doesn’t know your gltf refers to /textures/foo.png and /binaries/bar.bin or whatever, these files will be missing in prod. the solution is to use a glb.