local TextService = game:GetService("TextService")
local playerID = player.UserId
local filteredTextResult = TextService:FilterStringAsync(text, playerID)
for i, v in pairs(game.Workspace.Signs:GetChildren()) do
v.Text.SurfaceGui.TextLabel.Text = tostring(filteredTextResult)
end
I can see it’s already solved but I want to give you the reason why - since it wasn’t elaborated on fully above. The reason this is happening is you’re trying to read a TextFilterResult (an Instance) as a string.
When you use TextService:FilterStringAsync, you’re not actually filtering it at that moment. You’re making an object (the TextFilterResult) which you can then use to filter stuff with.
Why is this good? Because it means that you can filter a string for each specific user. Let’s say you have a radio - instead of filtering messages using FilterForBroadcast, which will filter it to the highest severity possible, you can give an appropriate filtered string for each individual user, which improves your user’s experience.
A lot of the complaints people make about the Roblox filter come from developers using Broadcast where it’s not appropriate - there are very few cases where broadcast strings are actually appropriate, or that there isn’t a better way to display the text.