Getting some sort of cyclic error, having trouble debugging it

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

Was working on a Roact-inspired custom chat gui, and I kept running into this error “Tables cannot be cyclic”. I’m pretty sure that means that a reference in a table was set to itself, somehow.

  1. What is the issue? Include screenshots / videos if possible!

I have no idea where this error is coming from! It might be the table I’m returning, but the thread where the error is occuring is a FireClient() call.



  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve previously tried this with RemoteFunctions, but their behaviour was inconsistent. When I was using those, wrapping the InvokeServer call in a pcall() just caused the client to hang forever? Also, I’m noticing two consistent outcomes:

1: The chat gui is parented to my playergui, but some script errors with “Tables cannot be cyclic.”

2: I don’t get the chat gui, but nothing errors, but nothing is also printed. I think that’s because one of the scripts hangs from waiting forever

I’ll try and restore the old RemoteFunctions setup and see what I can do there for now. Any help is appreciated!

5 Likes

A cyclic table means that it has a reference to it inside of it, yes. That means the table returned from your RoactChatConstructor module is cyclic, but the reason it is erroring on the FireClient line is because you cannot send a cyclic table through a RemoteEvent.

Could you upload the entire module?

2 Likes




Apologies if some threads may not be visible, but here it is. I’m not sure where the cyclic reference might come from. I am also looking to expand my knowledge of Roact, so that I can use it more effectively

2 Likes

Could you send the code as text instead of screenshots? Write the code between two ``` symbols to create a code block.

1 Like
local Roact = require(game:GetService("ReplicatedStorage"):WaitForChild("Roact"))

local RobloxChatGui = Roact.Component:extend("RobloxChatGui")

function RobloxChatGui:init()
   self.props.Signals = {
   	TextBoxFocusLost = Instance.new("BindableEvent"),
   	OnAnyHover = Instance.new("BindableEvent")
   }
   self.state = {
   	EntireChatVisible = true,
   	ChatBarVisible = true,
   	GlobalTransparency = 0.6
   }
end

function RobloxChatGui:render()
   local ScreenGui = Roact.createElement("ScreenGui", {
   	Enabled = self.state.EntireChatVisible,
   	ResetOnSpawn = false,
   	DisplayOrder = 6 --actual display order used by lua chat system
   }, {
   	MasterFrame = Roact.createElement("Frame", {
   		Name = "MasterFrame",
   		BackgroundTransparency = 1,
   		Size = UDim2.new(0.3, 0, 0.292, 0),
   		Visible = true,
   		[Roact.Event.MouseEnter] = function ()
   			self.props.Signals.OnAnyHover:Fire()
   		end,
   		[Roact.Event.MouseMoved] = function ()
   			self.props.Signals.OnAnyHover:Fire()
   		end
   	}, {
   		ChatBarFrame = Roact.createElement("Frame", {
   			BackgroundColor3 = Color3.fromRGB(0, 0, 0),
   			BackgroundTransparency = self.state.GlobalTransparency,
   			Visible = self.state.ChatbarVisible,
   			Position = UDim2.new(0, 0, 1, -42),
   			Size = UDim2.new(1, 0, 0, 42),
   			BorderSizePixel = 0,
   			[Roact.Event.MouseEnter] = function ()
   				self.props.Signals.OnAnyHover:Fire()
   			end,
   			[Roact.Event.MouseMoved] = function ()
   				self.props.Signals.OnAnyHover:Fire()
   			end
   		}, {
   			BoxFrame = Roact.createElement("Frame", {
   				BackgroundColor3 = Color3.fromRGB(255, 255, 255),
   				Visible = true,
   				Position = UDim2.new(0, 7, 0, 7),
   				Size = UDim2.new(1, -14, 1, -14),
   				BackgroundTransparency = self.state.GlobalTransparency,
   				BorderSizePixel = 0,
   				[Roact.Event.MouseEnter] = function ()
   					self.props.Signals.OnAnyHover:Fire()
   				end,
   				[Roact.Event.MouseMoved] = function ()
   					self.props.Signals.OnAnyHover:Fire()
   				end
   			}, {
   				ChatBar = Roact.createElement("TextBox", {
   					BackgroundTransparency = 1,
   					AnchorPoint = Vector2.new(0.5, 0.5),
   					Position = UDim2.new(0.5, 0, 0.5, 0),
   					Size = UDim2.new(1, -10, 1, -10),
   					SelectionStart = -1,
   					Visible = true,
   					PlaceholderColor3 = Color3.new(0, 0, 0),
   					PlaceholderText = "To chat click here or press '/' key",
   					FontFace = Font.fromEnum(Enum.Font.SourceSansBold),
   					LineHeight = 1,
   					TextSize = 18,
   					TextTransparency = 0.4,
   					TextXAlignment = Enum.TextXAlignment.Left,
   					TextYAlignment = Enum.TextYAlignment.Top,
   					TextEditable = true,
   					ClearTextOnFocus = false,
   					Text = "",
   					TextColor3 = Color3.fromRGB(27, 42, 53),
   					TextWrapped = true,
   					[Roact.Event.FocusLost] = function (...)
   						self.props.Signals.TextBoxFocusLost:Fire(...)
   					end,
   					[Roact.Event.MouseEnter] = function ()
   						self.props.Signals.OnAnyHover:Fire()
   					end,
   					[Roact.Event.MouseMoved] = function ()
   						self.props.Signals.OnAnyHover:Fire()
   					end
   				})
   			})
   		}),
   		ChatChannel = Roact.createElement("Frame", {
   			BackgroundColor3 = Color3.fromRGB(0, 0, 0),
   			BackgroundTransparency = self.state.GlobalTransparency,
   			BorderColor3 = Color3.fromRGB(27, 42, 53),
   			Position = UDim2.new(0, 0, 0, 2),
   			Size = UDim2.new(1, 0, 1, -46),
   			Visible = true,
   			BorderSizePixel = 0,
   			[Roact.Event.MouseEnter] = function ()
   				self.props.Signals.OnAnyHover:Fire()
   			end,
   			[Roact.Event.MouseMoved] = function ()
   				self.props.Signals.OnAnyHover:Fire()
   			end
   		}, {
   			Scroller = Roact.createElement("ScrollingFrame", {
   				Position = UDim2.new(0, 0, 0, 3),
   				Size = UDim2.new(1, -4, 1, -6),
   				Visible = true,
   				CanvasSize = UDim2.new(0, 0, 0, 18),
   				BorderSizePixel = 0,
   				BackgroundTransparency = 1,
   				[Roact.Event.MouseEnter] = function ()
   					self.props.Signals.OnAnyHover:Fire()
   				end,
   				[Roact.Event.MouseMoved] = function ()
   					self.props.Signals.OnAnyHover:Fire()
   				end
   			}, {
   				UIListLayout = Roact.createElement("UIListLayout", {
   					Padding = UDim.new(0, 0),
   					Name = "UIListLayout",
   					FillDirection = Enum.FillDirection.Vertical,
   					SortOrder = Enum.SortOrder.LayoutOrder,
   					VerticalAlignment = Enum.VerticalAlignment.Top
   					
   				})
   			})
   		})
   	})
   })
   return ScreenGui
end

return function(PlayerToMountTo:Player)
   local Element = Roact.createElement(RobloxChatGui)
   local Handle = Roact.mount(Element, PlayerToMountTo.PlayerGui, "RobloxChatGui")
   return {Element = Element, Handle = Handle}
end
2 Likes

I cant really make sense of the code since I’m on mobile, but if i remember correctly this is when you reference a table inside of itself. It happens because you cannot encode a table that references itself into json, meani ngf you will obly get this error if you try to send it somewhere. Example of a cyclyc table: local a = {} a.a = a

2 Likes

I honestly have no idea why it’s happening. I believe it is just a problem with roact. You could maybe live with it by not sending the Handle using remotes?

1 Like

I’ll try putting the chat constructor in Chat, and just let the client require it. I was hoping to use a table of remote events in props to easily hook onto events such as focus lost. Eh, I’ll just try sending the whole thing to the server directly from the constructor. I was also having issues with Roact handling a textbox’s focus lost event, so this should hopefully solve it.

I do still want to see if this was possible in the future, but oh well.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.