Incorrect documentation for GetAttribute

The return summary states

The attribute which has been assigned to the given name. If no attribute has been assigned then nil is returned

The second sentence is incorrect, if no attribute has been assigned then nothing is returned.


This also means that the Variant return type is incorrect. Variant implies that some value is returned, but when the attribute doesn’t exist it returns 0 values. WorldRoot:Raycast originally had a Tuple return type because of this (it returned nothing when nothing was hit, was later changed to return nil in such cases).

1 Like

I do not believe this is specific to GetAttribute but also present for DataStore:GetAsync, Plugin:GetSetting, and other methods which return a Variant.

I suspect I know why this is, but would need to dig into it a little further to verify my theory. For clarity, GetAttribute should return nil.


Should be important to note that the distinction between “empty” and “nil” is somewhat technical / only useful to know in specific cases and so any documentation on it returning one or the other should be written in a way not to confuse new developers. I can imagine the current version was written the way it is because that’s how most developers will interpret it and it gets the point across quickly.


At the very least, the subsequent result is nil. So the way developers interact with the returned value won’t change.

print(workspace:GetAttribute("whatever") == nil) prints true


The call to GetAttribute there will get the first result or nil, in a position where it expands to 1 result it won’t matter.

Here is an example where having it return nil instead of none is important.

print(type(workspace:GetAttribute"impossible name"))
--> script:1: missing argument #1

GetAsync was recently changed to indicate that it returns Tuple. RemoveAsync also had its return type changed to Tuple, since when there is no data for the key it returns nothing.

It would make sense for GetAttribute, GetAsync, RemoveAsync, GetSetting, and other methods to return nil instead of none. It seems that GetAsync and RemoveAsync returning nothing is intended, considering that the return types were changed to match the actual behavior (and not changing the behavior to match the return types).