{"record":{"id":"a46929fc4af3bfd8","repo":"mrdoob/three.js","slug":"three-objectloader-can-t-parse-url-e-messag","errorCode":null,"errorMessage":"THREE.ObjectLoader: Can't parse ${url}. ${e.message}","messagePattern":"THREE\\.ObjectLoader: Can't parse (.+?)\\. (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/loaders/ObjectLoader.js","lineNumber":183,"sourceCode":"\t\tconst path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;\n\t\tthis.resourcePath = this.resourcePath || path;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tconst text = await loader.loadAsync( url, onProgress );\n\n\t\tlet json;\n\n\t\ttry {\n\n\t\t\tjson = JSON.parse( text );\n\n\t\t} catch ( e ) {\n\n\t\t\tthrow new Error( 'THREE.ObjectLoader: Can\\'t parse ' + url + '. ' + e.message );\n\n\t\t}\n\n\t\tconst metadata = json.metadata;\n\n\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\tthrow new Error( 'THREE.ObjectLoader: Can\\'t load ' + url );\n\n\t\t}\n\n\t\treturn await scope.parseAsync( json );\n\n\t}\n\n\t/**\n\t * Parses the given JSON. This is used internally by {@link ObjectLoader#load}\n\t * but can also be used directly to parse a previously loaded JSON structure.","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/loaders/ObjectLoader.js#L165-L201","documentation":"Thrown by ObjectLoader when the text loaded from url cannot be parsed by JSON.parse. This happens before any three.js structure validation - the file content is not valid JSON at all (syntax error, truncated, or non-JSON body). The original parse error message is appended for diagnosis.","triggerScenarios":"Calling objectLoader.load(url, onLoad) or loadAsync(url) where the server returns an HTML error page, a binary file, a .glb (binary) instead of .json, truncated JSON due to network interruption, or a JSON file with trailing commas/comments (which strict JSON.parse rejects).","commonSituations":"Loading a .gltf or .glb binary with ObjectLoader instead of GLTFLoader. Server returning a 200 with an HTML error/spa page. Hand-edited JSON with comments. Proxied response that injected HTML. File saved with BOM or wrong encoding.","solutions":["Verify the file is a valid three.js JSON scene/object (produced by toJSON() or ObjectExporter); validate it at jsonlint.com.","If loading glTF/GLB, use GLTFLoader, not ObjectLoader.","Check the network response body - confirm it starts with '{' and is JSON, not an HTML page.","Re-export the model with scene.toJSON() and load the resulting .json.","Remove JSON comments/trailing commas and ensure UTF-8 encoding without BOM."],"exampleFix":"// before: pointing a binary/text asset at ObjectLoader\nobjectLoader.load('model.glb', onLoad);\n\n// after: use the right loader, or a valid JSON export\nconst gltfLoader = new THREE.GLTFLoader();\ngltfLoader.load('model.glb', (g) => onLoad(g.scene));\n// or, for a real three.js JSON scene:\nobjectLoader.load('scene.json', onLoad);","handlingStrategy":"try-catch","validationCode":"function looksLikeThreeJSON(text) {\n  const trimmed = text.trimStart();\n  if (!trimmed.startsWith('{')) return false;\n  try { JSON.parse(text); return true; } catch { return false; }\n}\n\nconst text = await fetch(url).then(r => r.text());\nif (!looksLikeThreeJSON(text)) throw new Error(`${url} is not valid JSON`);","typeGuard":"function isParsableJSON(text) {\n  try { JSON.parse(text); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  const obj = await objectLoader.loadAsync(url);\n} catch (e) {\n  if (/Can't parse/.test(e.message)) {\n    console.error(`${url} is not valid JSON - use GLTFLoader for glTF/GLB`);\n  }\n  throw e;\n}","preventionTips":["Use GLTFLoader for .gltf/.glb, not ObjectLoader.","Validate exported JSON with scene.toJSON() round-trips.","Inspect the response body - an HTML page means a routing/CORS problem."],"tags":["threejs","loader","json","parsing","objectloader","serialization"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}