String coercion broken Since Server Build Luau 2025-03-18.13925620430
closed
WolfGang Senizen
The update added the functionality for this 'string and uuid compatibility'
But it seems all functions that accept strings now imply they accept uuid's instead and normal lua type coercion is broken because of this I think.
Reproduction
- Create a script with the following in lua
ll.OwnerSay(1)
- Save it
You should receive the error
lua_script:1: invalid argument #1 to 'OwnerSay' (uuid expected, got number)
The functions used to accept any variable that could be coerced to string in the default lua manner.
Update
Luau 2025-03-20.13977389313
The uuid error has been fixed, methods now say string, but the earlier type coercion seems to still be gone.
ll.OwnerSay(1)
Now errors
lua_script:1: invalid argument #1 to 'OwnerSay' (string expected, got number)
Log In
H
Harold Linden
closed
The reasoning for the new behavior of not coercing
number
-> string
was described below, we're trying to prevent accidental footguns RE internal allocations in the binding code.H
Harold Linden
Hi WolfGang, thanks for reporting this!
That new behavior's intentional (minus the wrong type in the error you mentioned, thanks for that!)
The only type coercion that _used_ to exist for
ll.*()
functions taking in strings was coering number
-> string
. There was no coercion to string for any other type, including integer
, which is why uuid
s weren't working for functions taking strings even though they have a __tostring
on their metatable and tostring(uuid_val)
worked.The only reason passing a
number
worked before is that (confusingly,) luaL_checkstring(L, arg_num)
will also accept a number, silently creating a new string within the binding code which counts against the memory limit for the script. It wasn't intentional, and we weren't aware of the behavior of that call.See https://github.com/luau-lang/luau/blob/e0b55a9cb1857bc699a20f0aa3099c7a495a0152/VM/src/laux.cpp#L171, https://github.com/luau-lang/luau/blob/e0b55a9cb1857bc699a20f0aa3099c7a495a0152/VM/src/lapi.cpp#L429 and https://github.com/luau-lang/luau/blob/e0b55a9cb1857bc699a20f0aa3099c7a495a0152/VM/src/lvmutils.cpp#L31 for reference.
The reason we didn't want that behavior is that if your script hits the memory limit due to that new string being allocated, you won't have a good stacktrace showing where / why you ran out of memory, because it just looks like
ll.OwnerSay()
's implementation caused you to run out of memory, even though the reason was the implicitly-allocated string due to coercion in the binding code.Going forward
ll.OwnerSay(`{some_val}`)
-- or
ll.OwnerSay(tostring(some_val))
is the way to go.
WolfGang Senizen
Harold Linden
Ahh, kind of a shame, but a good reason.
Thanks for the detailed reply.
And good work on the fixes so far.