Core.utils.prims.move_prim can terminate IsaacSim

Hey!

I’m using move_prim to rename multiple prims in my scene after they have been moved to other parents during a simulation.

Since I didn’t find another way, I record the original path for each prim (and have a new id-attribute to track prims throughout the simulation). At the start of a simulation, I reset the paths with move_prim.

I now have a list of current_name → original_name pairs and run move_prim for each pair. This works most often as expected, but now I triggered the case in which both the parent and a child have been renamed. This currently leads to the case, that I call move_prim(‘/World/Foo/Bar’, '/World/ASD/foo) where a is not a valid prim anymore because /World/Foo was already renamed to /World/XYZ.

This of course can’t work, the problem (aka bug) is now that IsaacSim dies instead of raising an exception:

"terminate called after throwing an instance of ‘pxrInternal_v0_22__pxrReserved__::UsdExpiredPrimAccessError’
what(): Used null prim
"

I know I should not try to use invalid prims here and I should check a IsValid for the source and the parent of the target, but I think even a wrong usage should not kill the whole application.

I did some more digging into the issue and think that the issue is somewhere else.

My Code now looks like this:

src_ok = self.stage.GetPrimAtPath(old).IsValid()
tgt_parent_ok = self.stage.GetPrimAtPath(Path(new).parent.as_posix()).IsValid()
tgt_ok = not self.stage.GetPrimAtPath(new).IsValid()

if not all([src_ok, tgt_parent_ok, tgt_ok]):
    continue

carb.log_warn(f"Renaming {old} to {new}")

try:
    prims_utils.move_prim(old, new) 
except Exception as e:
    carb.log_error(f"Error renaming {old} to {new}: {e}")
    continue
carb.log_warn(f"Renamed {old} to {new}")

So I think I can claim that this renaming should be valid because the source is valid, there is nothing yet at the target and the parent of the target prim exists.

The move_prim also does not trigger an Exception and even if the underlying C+±code triggers something, the second log_warn should not be executed.

This is my output (I currently run the renaming-function recursively as soon as I successfully renamed a prim to make sure that I don’t try to do invalid renames. Not the most efficient method, but safe)

2025-03-31 (...)  Renaming 5 prims                                                               
2025-03-31 (...)  Renaming /World/Conveyors/ConveyorTrack_T/Belt_01/Cardbox_C1_712936021172217926297711806828 to /World/Zones/outbound_zone_01/Positions/P1_02/Pallet_A1_07/items/Cardbox_C1_712936021172217
2025-03-31 (...)  Renamed /World/Conveyors/ConveyorTrack_T/Belt_01/Cardbox_C1_712936021172217926297711806828 to /World/Zones/outbound_zone_01/Positions/P1_02/Pallet_A1_07/items/Cardbox_C1_712936021172217 
2025-03-31 (...)  Renaming 4 prims                                                                                                                                                                       
2025-03-31 (...)  Renaming /World/forklift/Pallet_A1_07 to /World/Zones/truck_zone_00/Positions/P1_02/Pallet_A1_07                           
2025-03-31 (...)  Renamed /World/forklift/Pallet_A1_07 to /World/Zones/truck_zone_00/Positions/P1_02/Pallet_A1_07                                                                                          
2025-03-31 (...)  Renaming 0 prims                                                                                                          
                                                                       
terminate called after throwing an instance of 'pxrInternal_v0_22__pxrReserved__::UsdExpiredPrimAccessError'                                                                                                
  what():  Used null prim

Is there a way to get a better debug output? It would be extremely valuable to know in which function the error happens.