BasePart:GetRootPart() typed as returns Instance but returns nil when BasePart is not parented to workspace (No type safety)

Found a bug where BasePart:GetRootPart() was assumed to return an instance but returned nil.

Maybe it’s a issue with the documentation and return type.



Expected behavior

Expected BasePart:GetRootPart() to never return nil

1 Like

Thanks for the report, we will look into this.

It’s worth pointing out that BasePart.AssemblyRootPart can be used instead, and shouldn’t have this issue

1 Like

Thanks for posting, we will need to update our docs. When you call BasePart:GetRootPart() or BasePart.AssemblyRootPart on a part that isn’t parented to the workspace, we expect the result to be nil. This is because the Assembly that the part belongs to won’t be assembled until it is parented to the workspace. As a result, the AssemblyRootPart of the part hasn’t been set and we return nil.

Our docs should indicate that GetRootPart() should optionally return an Instance. We’ll get this fixed ASAP!

Could be this used as a work-around?

local function GetRootPart(p: BasePart)
	local originalParent = p.Parent
	p.Parent = workspace
	local rootPart = p:GetRootPart() or p.AssemblyRootPart
	p.Parent = originalParent
	return rootPart
end

print(GetRootPart(Instance.new("Part"))) -- Part

Great question! That does guarantee that GetRootPart() will never return nil, but I think returning nil is the “right” thing to do here.

Internally to the Roblox engine, each BasePart goes through various Stages in something we call the WorldStage Pipeline which processes them in various ways (e.g. forms Assemblies, steps animated joints, etc.). When a BasePart is created, it doesn’t enter the WorldStage Pipeline until is parented to the workspace. This is for efficiency: until these parts are put in a workspace, nothing in the engine can see or interact with them, so there’s no reason to put them into the Pipeline.

Calling GetRootPart()/AssemblyRootPart assumes that the part has been Assembled, and therefore must be in the Pipeline. In this case, returning nil signals that the root part hasn’t been set for the part yet, which is accurate. Putting the part into the workspace and then removing it is inefficient since we’re putting it into the Pipeline and then immediately removing it, so it’s best to not do it in the first place.

1 Like