{"record":{"id":"aeb4ef65d56157be","repo":"BabylonJS/Babylon.js","slug":"babylonscenepathtoobjectconverter-no-collection","errorCode":null,"errorMessage":"BabylonScenePathToObjectConverter: no ${collectionName} instance found with uniqueId ${uniqueId} (path \"${path}\").","messagePattern":"BabylonScenePathToObjectConverter: no (.+?) instance found with uniqueId (.+?) \\(path \"(.+?)\"\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/glTF/2.0/Extensions/babylonScenePathToObjectConverter.ts","lineNumber":167,"sourceCode":"        }\r\n\r\n        if (parts.length < 2) {\r\n            throw new Error(`BabylonScenePathToObjectConverter: path \"${path}\" is missing an instance id.`);\r\n        }\r\n\r\n        // parseInt would accept \"12abc\" as 12; require an all-digits id so a malformed path fails\r\n        // loudly instead of binding to the wrong instance.\r\n        if (!/^\\d+$/.test(parts[1])) {\r\n            throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId \"${parts[1]}\" in path \"${path}\".`);\r\n        }\r\n        const uniqueId = parseInt(parts[1], 10);\r\n        if (!Number.isFinite(uniqueId) || uniqueId < 0) {\r\n            throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId \"${parts[1]}\" in path \"${path}\".`);\r\n        }\r\n\r\n        const instance = this._lookupInstanceByUniqueId(collectionName, uniqueId);\r\n        if (!instance) {\r\n            throw new Error(`BabylonScenePathToObjectConverter: no ${collectionName} instance found with uniqueId ${uniqueId} (path \"${path}\").`);\r\n        }\r\n\r\n        // No property after the id → the ref itself is just a handle to the instance.\r\n        // The accessor's `get` and `getTarget` both return the instance.\r\n        if (parts.length === 2) {\r\n            return {\r\n                object: instance,\r\n                info: this._buildIdentityAccessor(instance),\r\n            };\r\n        }\r\n\r\n        // Walk the leaf descriptors for the requested property path. We keep this\r\n        // very simple right now: only one segment after the id is supported, which\r\n        // covers every property the initial leaves expose. Nested paths can be\r\n        // added later by extending the walker.\r\n        if (parts.length > 3) {\r\n            throw new Error(`BabylonScenePathToObjectConverter: nested property paths are not yet supported (path \"${path}\").`);\r\n        }\r","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/glTF/2.0/Extensions/babylonScenePathToObjectConverter.ts#L149-L185","documentation":"After validating the id format, convert() looks up the live instance by uniqueId within the named collection via _lookupInstanceByUniqueId. If no instance with that id currently exists in the collection, the library throws — a valid-looking path can still dangle if the target object was disposed, not yet created, or belongs to a different scene/collection.","triggerScenarios":"convert() called with a well-formed path like \".../transformNodes/42/position\" where no TransformNode with uniqueId 42 exists: the node was disposed before the pointer was resolved, the pointer was serialized from a previous scene/run, the id belongs to another collection type, or resolution happens before the loader finished instantiating objects.","commonSituations":"Storing JSON Pointers persistently across scene reloads (uniqueIds are per-session, not stable across runs); resolving animation/extension targets during loading before all nodes exist; disposing objects while async processing still references them.","solutions":["Re-derive the pointer from the live object right before converting (use instance.uniqueId of the current scene) rather than reusing a stored path.","Check that the target object exists (e.g. scene.getTransformNodeByUniqueId or the collection's lookup) before calling convert(), and skip/remove dead references.","If pointers must persist, store stable identifiers (names/glTF indices) and rebuild uniqueId-based paths at load time after the scene is fully constructed.","Ensure the resolver runs after the glTF loader has finished creating all scene objects."],"exampleFix":"// before\nconverter.convert(storedPath); // id from a previous session\n// after\nconst path = `${BABYLON_SCENE_OBJECT_MODEL_PREFIX}transformNodes/${currentNode.uniqueId}/position`;\nconverter.convert(path);","handlingStrategy":"try-catch","validationCode":"const node = scene.getTransformNodeByUniqueId(uniqueId);\nif (!node) {\n  // skip stale pointer instead of converting\n  return null;\n}\nconverter.convert(`${BABYLON_SCENE_OBJECT_MODEL_PREFIX}transformNodes/${uniqueId}/position`);","typeGuard":"null","tryCatchPattern":"try {\n  const info = converter.convert(path);\n} catch (e) {\n  if (String(e).includes(\"no \")) {\n    // dangling instance reference: rebuild the path from live objects or drop it\n  }\n}","preventionTips":["Never persist uniqueId-based pointers across scene reloads; store stable ids and rebuild paths after load","Resolve pointers only after the glTF load completes","Remove or refresh references when disposing scene objects"],"tags":["gltf","babylon","stale-reference","scene-lifecycle"],"backgroundTag":"stale-object-reference","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}