mrdoob/three.js · error

THREE.ObjectLoader: Can't load ${url}

Error message

THREE.ObjectLoader: Can't load ${url}

What it means

Thrown by ObjectLoader after successful JSON parse when the parsed object is not a loadable three.js scene/object: either json.metadata is undefined, metadata.type is undefined, or metadata.type (lowercased) equals 'geometry'. Legacy standalone geometry files from older three.js revisions are explicitly rejected; ObjectLoader only handles objects/scenes.

Source

Thrown at src/loaders/ObjectLoader.js:191

		const text = await loader.loadAsync( url, onProgress );

		let json;

		try {

			json = JSON.parse( text );

		} catch ( e ) {

			throw new Error( 'THREE.ObjectLoader: Can\'t parse ' + url + '. ' + e.message );

		}

		const metadata = json.metadata;

		if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

			throw new Error( 'THREE.ObjectLoader: Can\'t load ' + url );

		}

		return await scope.parseAsync( json );

	}

	/**
	 * Parses the given JSON. This is used internally by {@link ObjectLoader#load}
	 * but can also be used directly to parse a previously loaded JSON structure.
	 *
	 * @param {Object} json - The serialized 3D object.
	 * @param {onLoad} onLoad - Executed when all resources (e.g. textures) have been fully loaded.
	 * @return {Object3D} The parsed 3D object.
	 */
	parse( json, onLoad ) {

		const animations = this.parseAnimations( json.animations );

View on GitHub (pinned to da05705fa3)

Solutions

  1. Ensure the file was produced by object.toJSON() or scene.toJSON() so it contains metadata.type === 'Object' or 'Scene'.
  2. For legacy geometry JSON, parse it with the appropriate legacy path or convert it: wrap it in a Mesh first, then export via scene.toJSON().
  3. Load geometry-only files separately (e.g. with BufferGeometryLoader) and build the mesh yourself.
  4. Open the JSON and confirm metadata.type is 'Object' or 'Scene', not 'geometry' or missing.

Example fix

// before: loading a legacy geometry.json (metadata.type === 'geometry')
objectLoader.load('old-geometry.json', onLoad); // throws 'Can't load'

// after: use the geometry loader, then wrap in a mesh
const geoLoader = new THREE.BufferGeometryLoader();
geoLoader.load('old-geometry.json', (geo) => {
  const mesh = new THREE.Mesh(geo, new THREE.MeshStandardMaterial());
  scene.add(mesh);
});
Defensive patterns

Strategy: validation

Validate before calling

function isLoadableObjectJSON(json) {
  const meta = json && json.metadata;
  if (!meta || meta.type === undefined) return false;
  const t = String(meta.type).toLowerCase();
  return t !== 'geometry';
}

const json = JSON.parse(text);
if (!isLoadableObjectJSON(json)) {
  throw new Error(`${url} is not a loadable three.js Object/Scene JSON`);
}

Type guard

function isSceneOrObjectJSON(json) {
  const type = json && json.metadata && json.metadata.type;
  return typeof type === 'string'
    && ['object', 'scene'].includes(type.toLowerCase());
}

Prevention

When it happens

Trigger: Loading a legacy three.js Geometry JSON export (metadata.type === 'geometry'), a JSON that is valid but not a three.js export (missing metadata), or a partial/hand-built JSON lacking the metadata block. Also loading an output from BufferGeometry.toJSON() directly rather than a Mesh/Scene.toJSON().

Common situations: Migrating old projects that saved geometry JSON. Loading a plain data JSON mistaken for a scene. Loading a geometry-only file produced by older exporters. Hand-authoring JSON without the metadata header.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/905305c812ee6408. Report an issue: GitHub.