{"record":{"id":"3c7923aa6602c15a","repo":"FyroxEngine/Fyrox","slug":"ticket-index-was-invalid","errorCode":null,"errorMessage":"Ticket index was invalid","messagePattern":"Ticket index was invalid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fyrox-core/src/pool/mod.rs","lineNumber":1084,"sourceCode":"                };\n                Ok((ticket, payload))\n            } else {\n                Err(PoolError::Empty(handle.into()))\n            }\n        } else {\n            Err(PoolError::InvalidGeneration(handle.generation))\n        }\n    }\n\n    /// Returns the value back into the pool using the given ticket. See [`take_reserve`] for more\n    /// information.\n    ///\n    /// [`take_reserve`]: Pool::take_reserve\n    #[inline]\n    pub fn put_back(&mut self, ticket: Ticket<T>, value: T) -> Handle<T> {\n        let record = self\n            .records_get_mut(ticket.index)\n            .expect(\"Ticket index was invalid\");\n        let old = record.payload.replace(value);\n        assert!(old.is_none());\n        let handle = Handle::new(ticket.index, record.generation);\n        std::mem::forget(ticket);\n        handle\n    }\n\n    /// Forgets that value at ticket was reserved and makes it usable again.\n    /// Useful when you don't need to put value back by ticket, but just make\n    /// pool record usable again.\n    #[inline]\n    pub fn forget_ticket(&mut self, ticket: Ticket<T>) {\n        self.free_stack.push(ticket.index);\n        std::mem::forget(ticket);\n    }\n\n    /// Returns total capacity of pool. Capacity has nothing about real amount of objects in pool!\n    #[inline]","sourceCodeStart":1066,"sourceCodeEnd":1102,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-core/src/pool/mod.rs#L1066-L1102","documentation":"Pool::put_back returns a previously take_reserve'd record to the pool using the ticket taken from take_reserve. The ticket's index must point to a valid pool record; if the ticket is stale, corrupted, duplicated, or belongs to another pool, records_get_mut returns None and the code panics.","triggerScenarios":"Calling put_back with a Ticket that was not obtained from take_reserve on this same pool, a ticket used twice (forgotten handles / double put_back), or a ticket from a different pool instance.","commonSituations":"Undo/redo or frame-delayed reinsertion logic that stores tickets across pool rebuilds; copying ticket values and putting back twice; mixing tickets between pools of the same type.","solutions":["Only use tickets returned by take_reserve on the same pool, exactly once","Ensure each take_reserve is matched by exactly one put_back (no duplicates)","Verify the pool was not recreated/cleared while the ticket was held"],"exampleFix":"// before\npool.put_back(old_ticket, value); // ticket already consumed\n\n// after\nlet (ticket, _) = pool.take_reserve(handle);\n// ... exactly once ...\nlet handle = pool.put_back(ticket, value);","handlingStrategy":"type-guard","validationCode":"// ensure ticket was produced by take_reserve on this pool and not yet consumed\nassert!(tickets.contains_key(&ticket.index));","typeGuard":null,"tryCatchPattern":"// pre-condition check instead of catch: track live tickets in a set; on drop/put_back remove them exactly once","preventionTips":["Never copy or clone Tickets; consume each exactly once","Keep take_reserve/put_back pairs in the same scope or RAII guard","Never share tickets across pool instances"],"tags":["panic","pool","ticket","invalid-handle"],"backgroundTag":"internal-invariant-violation","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}