Make missing property error better understandable

I have had 2 times now that I wanted to change a decal’s image. What I did was

workspace.Baseplate.Decal = "rbxassetid://12521941"

Of course this errors, because it shouldve been

workspace.Baseplate.Decal.Texture = "rbxassetid://12521941"

However Roblox gives a confusing error in this case. The error is:
Decal is not a valid member of part.
This is really confusing because its basically telling me that i didn’t reference the instance correctly, while its actually the property i forgot to reference.

My idea is that these kids of coding mistakes get an error that are less confusing. As example the error could be: Can’t assign string to decal.
This would be a lot clearer, and save people many headaches.

1 Like

I don’t believe this is what’s going on here, since __newindex works for properties, methods and members.
What’s actually happening is that it thinks you’re attempting to access a property, because you can’t assign children manually.

It can be fixed, but right now it’s showing the intended output, because it’s what the metamethods have been set up for.

2 Likes

Events, methods, and callbacks are all considered members of instances. I think the error message makes sense given that context. The engine cannot make assumptions about whether you’re trying to set the value of a property or set a callback, so member seems like the right wording.

4 Likes

Actually if you assign to events you get the same message:

> workspace.Changed = true
18:42:56.803 - Changed is not a valid member of Workspace
18:42:56.808 - Stack Begin
18:42:56.808 - Script 'workspace.Changed = true', Line 1
18:42:56.808 - Stack End

Which is just plain wrong.

The message should probably be changed to something like

Member/Child Changed of Workspace cannot be assigned to
2 Likes

Given that there is no ambiguity between name collisions between Properties / Events / Child-Access, the engine doesn’t have to “assume” anything here to give a better error message.

The error message absolutely does suck, it could easily give you more, and more relevant information.

part.Name = true
Gives:  bad argument #3 to 'Name' (string expected, got boolean)
Desired: Tried to assign a boolean to Part::Name which is a string property

part.Changed = true
Gives: Changed is not a valid member of Part
Desired: Tried to assign to Part::Changed, which is an event, not a property

part.Decal = 'foobar'
Current: Decal is not a valid member of Part
Desired: Tried to assign to property Part::Decal which does not exist
Maybe even adding: (The Part has a child named `Decal`, did you mean to index that?)

part.Destroy()
Gives: Expected ':' not '.' calling member functio Destroy
Desired: All good! This one was already fixed... remember the old nonsense?

IMO it absolutely should call it a “property” and not a “member” in the particular case that the OP is talking about. The only things that you can assign to are properties and callbacks… and callbacks are just an implementation detail, they’re effectively just properties that have a function as their value from the perspective of the developer. The only people who know or care about the difference are people who would understand the error message perfectly fine either way.

7 Likes

It’s entirely possible that things like these are there for api consistency.
This is likely because __newindex is being called, making x.y = z effectively a __newindex(x, y, z), hence the error message.

Yeah, that’s obviously the reason why the error message is what it is… but that’s an implementation detail that the developer shouldn’t have to care about, so it’s not a good reason for it to be that way.