{"record":{"id":"4c5085567545905e","repo":"mrdoob/three.js","slug":"three-batchedmesh-invalid-instanceid-instanceid","errorCode":null,"errorMessage":"THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instance is either out of range or has been deleted.","messagePattern":"THREE\\.BatchedMesh: Invalid instanceId (.+?)\\. Instance is either out of range or has been deleted\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/objects/BatchedMesh.js","lineNumber":458,"sourceCode":"\t\t\t\tthrow new Error( 'THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Validates the instance defined by the given ID.\n\t *\n\t * @param {number} instanceId - The instance to validate.\n\t */\n\tvalidateInstanceId( instanceId ) {\n\n\t\tconst instanceInfo = this._instanceInfo;\n\t\tif ( instanceId < 0 || instanceId >= instanceInfo.length || instanceInfo[ instanceId ].active === false ) {\n\n\t\t\tthrow new Error( `THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instance is either out of range or has been deleted.` );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Validates the geometry defined by the given ID.\n\t *\n\t * @param {number} geometryId - The geometry to validate.\n\t */\n\tvalidateGeometryId( geometryId ) {\n\n\t\tconst geometryInfoList = this._geometryInfo;\n\t\tif ( geometryId < 0 || geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {\n\n\t\t\tthrow new Error( `THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometry is either out of range or has been deleted.` );\n\n\t\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/objects/BatchedMesh.js#L440-L476","documentation":"Thrown by BatchedMesh.validateInstanceId() when the instanceId is negative, greater than or equal to the instance info array length, or refers to a deleted (inactive) instance. Many BatchedMesh APIs call validateInstanceId internally, so passing a stale or out-of-range id triggers it.","triggerScenarios":"Using an instanceId returned before a deleteInstance() call; caching an id across a setInstanceCount() shrink; passing an unvalidated index from user input; off-by-one when iterating instance ids.","commonSituations":"Caching instance ids in application data structures that outlive the instance; deleting instances and then referencing them; shrinking maxInstanceCount while ids above the new cap are still referenced.","solutions":["Track instance lifecycle: clear any cached id after deleteInstance() returns.","Before using an id, call `batch.validateInstanceId(id)` in a try/catch, or bound-check against `batch.instanceCount` and track active ids yourself.","Avoid shrinking maxInstanceCount below currently-used ids (setInstanceCount throws separately for that)."],"exampleFix":"// before\nbatch.deleteInstance( id );\nbatch.setMatrixAt( id, matrix ); // id now invalid\n\n// after\nbatch.deleteInstance( id );\n// stop referencing `id`; remove it from your id->object map","handlingStrategy":"validation","validationCode":"function isValidInstanceId( batch, id ) {\n  const info = batch._instanceInfo;\n  return id >= 0 && id < info.length && info[ id ].active === true;\n}\n\nif ( ! isValidInstanceId( batch, id ) ) throw new RangeError( `Invalid instanceId ${ id }` );","typeGuard":"const isActiveInstance = ( batch, id ) => isValidInstanceId( batch, id );","tryCatchPattern":"try {\n  batch.getMatrixAt( id, matrix );\n} catch ( e ) {\n  if ( /Invalid instanceId/.test( e.message ) ) {\n    // id was deleted or out of range; skip this entity\n  } else throw e;\n}","preventionTips":["Invalidate cached instance ids when deleteInstance() is called.","Track active ids in your own map rather than assuming contiguity.","Validate ids before any get/setMatrixAt, setColorAt, or visibility call."],"tags":["batched-mesh","instance","validation","lifecycle"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}