Requiring module doesn't work, gives me "Layered Accessories JSON is invalid!" warning

I have this module that works properly, no errors marked, checked every single function, there is absolutely nothing wrong with the code, but when i require it, it simply yields the script (apparently) with this warning:

  21:49:04.301  Layered Accessories JSON is invalid!  -  Studio

I have no idea what this means, using debug.traceback() marks the error to be on the require function, just to be certain there weren’t errors with the module, I used pcall() on the entirety of it, marked no errors, worked properly, this only happens when i require the module and I don’t know why, I don’t even understand what the error means.

Try renaming the module script, moving the module script to a different location, deleting the module script entirely & copying the code into a different ModuleScript instance. Make sure there isn’t hidden code maliciously added (sometimes a line will end with a ton of spaces and then a malicious bit of code).

1 Like

Ok, I will try that, I don’t think it´s anything malicious given that i made it from scratch though.

I think this is an error on Roblox’s side, and not your code. Not sure though.

1 Like

I’m not having this problem with other modules though, but i will take that in mind if i don´t find a solution.

Can you show us the module script code?

Alright, it’s kind of messy though, i added some comments so maybe that helps :sweat_smile:


local Card = {}

Card.__index = Card
Card.__tostring = function(Table) return Table.Name end

function Card.new(Properties , player)
	local self = setmetatable({} , Card) -- Giving acces to module functions
	self.Name = "boyparis"

	self.Color = 6865280869
	self.Image = 6873565000
	self.Power = 500
	self.Health = 500

	do --Read only properties
		self.WhiteCost = 10
		self.RedCost = 10
		self.BlueCost = 10
		self.GreenCost = 10
		self.YellowCost = 10

		self.Counters = 0
		self.Slot = "Deck"
	end

	self.Owner = player
	self.Events = {}

	do -- Events
		self.Events.DamageTaken = {}
		self.Events.Destroyed = {}
		self.Events.Targeted = {}
		self.Events.PowerChanged = {}
		self.Events.CountersChanged = {}
		self.Events.TurnEnd = {}
		self.Events.TurnStart = {}
		self.Events.CardDrawn = {}
		self.Events.CardDestroyed = {}
		self.Events.OnSelfCast = {}
		self.Events.OnAllyCast = {}
		self.Events.OnEnemyCast = {}
		self.Events.EnemyDestroyed = {}
		self.Events.AllyDestroyed = {}
		self.Events.Transformed = {}
	end

	for i , v in pairs(Properties) do
		if self[i] then
			self[i] = v
		end
	end

	self.Model = game.InsertService:LoadAsset(Properties.Model or 6892715376):FindFirstChildWhichIsA("Model")
	self.CardObject = self:RenewGui()

	local proxy = setmetatable({keys = {"Name", "Color", "Image", "Power", "Health", "WhiteCost", "RedCost", "GreenCost", "BlueCost", "YellowCost", "Counters", "Slot"}} , {
		__index = function(Tab , key) 
			if self[key] then
				return self[key]
			end
		end,
		__newindex = function(Tab , key , val) -- This entire function just calls any functions within the card's events
			if self[key] then

				if table.find({"Power", "Health", "WhiteCost", "RedCost", "GreenCost", "BlueCost", "YellowCost", "Counters"} , key) then
					local EventTable = nil
					local Args = nil

					if key == "Power" then
						EventTable = self.Events.PowerChanged
						Args = {self , val - self[key]}
					end

					if key == "Health" then
						if self[key] < val then
							EventTable = self.Events.DamageTaken
							Args = {self , val - self[key]}
						elseif val <= 0 then
							EventTable = self.Events.Destroyed
							Args = {self}
						end
					end

					if key == "Counters" then
						EventTable = self.Events.AttackChanged
						Args = {self , val - self[key]}
					end

					self[key] = math.clamp(val , 0 , math.huge)

					if EventTable then

						for i , Effect in pairs(EventTable) do
							Effect(Args)
						end
					end

				elseif table.find({"Name", "Color", "Image"} , key) then
					self[key] = val
				else
					warn("Attempt to set read only property")
				end

			end
		end
	})

	return proxy
end

function Card:SpawnModel(slotGui) --Just some visual effect thing
	local effect = game.ReplicatedStorage.CastEffect:Clone() --Spawn effect
	effect:SetPrimaryPartCFrame(slotGui.Parent.CFrame - Vector3.new(0,6,0)) --Make it appear in the correct slot
	effect.Parent = workspace

	local tween = game:GetService("TweenService"):Create(effect.PrimaryPart,TweenInfo.new(0.35),{CFrame = CFrame.new((effect.PrimaryPart.Position + Vector3.new(0,8,0))) * CFrame.Angles(0,math.rad(120),0)}) --Tween 
	tween:Play()
	tween.Completed:Wait()

	local model = self.Model
	model:SetPrimaryPartCFrame(self.Parent.Parent.CFrame)
	model:SetPrimaryPartCFrame(CFrame.new(model.PrimaryPart.Position + Vector3.new(0,6,0)))
	model.Parent = self.CardObject
	model.Humanoid.Animator:LoadAnimation(model.IdleAnimation):Play()

	local tween = game:GetService("TweenService"):Create(effect.PrimaryPart,TweenInfo.new(0.2),{CFrame =(effect.PrimaryPart.CFrame * CFrame.Angles(0,math.rad(240),0))}) --Tween 
	tween:Play()
	tween.Completed:Wait()	

	local tween = game:GetService("TweenService"):Create(effect.PrimaryPart,TweenInfo.new(0.2),{CFrame = (effect.PrimaryPart.CFrame * CFrame.Angles(0,math.rad(360),0))}) --Tween 
	tween:Play()
	tween.Completed:Wait()	
	effect:Destroy()
end

function Card:RenewGui() --Copies a pre-made gui from replicatedstorage and adjusts it

	local InsertService = game:GetService("InsertService")
	local BorderDec =  InsertService:LoadAsset(tonumber(self.Color))
	local DisplayDec =  InsertService:LoadAsset(self.Image)
	local card =  game.ReplicatedStorage.EmptyCard:Clone()
	card.Name = self.Name
	card.NameLabel.Text = self.Name
	card.Border.Image = BorderDec.Decal.Texture
	card.Display.Image = DisplayDec.Decal.Texture 
	BorderDec:Destroy()
	DisplayDec:Destroy()
	card.Power.Text = self.Power
	card.Health.Text = self.Health
	card.ModelVal.Value = self.Model
	local distance = 0.13

	local colors = {"White","Yellow","Green","Blue","Red",}

	for i , color in pairs(colors) do
		card.Costs[color].CostLabel.Text = self[color .. "Cost"]

		if tonumber(card.Costs[color].CostLabel.Text) <= 0 then 
			card.Costs[color].Visible = false
		else
			card.Costs[color].Position = UDim2.new(distance,0,0.91, 0)
			distance += 0.075
		end
	end

	return card
end

Card.DefaultCards = {
	Card.new({
		["Name"] = "Boyparis",
		["Color"] = 6865280869,
		["Image"] = 6873565000,
		["Power"] = 400,
		["Health"] = 5000,
		["WhiteCost"] = 10,
		["RedCost"] = 3,
		["BlueCost"] = 3,
		["GreenCost"] = 3,
		["YellowCost"] = 3,
		["Model"] = 6971743255
	}),

	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865283271,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865283271,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865281448,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865282008,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865280869,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
	Card.new({
		["Name"] = "Nil",
		["Color"] = 6865282709,
		["Image"] = 6865303020,
		["Power"] = 50,
		["Health"] = 50,
		["WhiteCost"] = 1,
		["RedCost"] = 1,
		["BlueCost"] = 1,
		["GreenCost"] = 0,
		["YellowCost"] = 0,
		["Model"] = 6892715376
	}),
}

return Card

If you made it from scratch then the only thing I can potentially think of is maybe a malicious plugin.

1 Like

Your code seems fine (from just scrolling through it). Can you try placing the module in another game?

Ok, it is very late where i live and i was expecting to wait several hours for a reply so i will have to get back to you in about 7 to 8 hours

1 Like

This still caused the warning, but returns the module successfully, that said, printing it gave me this:

 {
                    ["DefaultCards"] =  ▶ {...},
                    ["RenewGui"] = "function",
                    ["SpawnModel"] = "function",
                    ["__index"] = "*** cycle table reference detected ***",
                    ["__tostring"] = "function",
                    ["new"] = "function"
                 }  -  Server - Script:1

That would corespond to this bit of code:

local Card = {}

Card.__index = Card
Card.__tostring = function(Table) return Table.Name end

function Card.new(Properties , player)
	local self = setmetatable({} , Card) -- Giving acces to module functions

I don’t understand why this counts as a “cycle table reference”
I guess it’s because you could make use of self.new() to make a new card, so you could potentially do something like this: self.new().new().new().new().new().new().new().new().new().new().new().new().new().new()

Yeah, I had to make a custom table by copying the module but removing the .new() function and setting that when the __index metamethod fires.

And that did the trick.

1 Like

That’s great! Good luck developing!

1 Like