Error with script

I’m getting this error with my script…(Screenshot of console found below)

Here’s the script that’s getting the error:

local productId = 1174490066 --your dev product for a song

local trelloboard = "(trelloboard here)" --the thing in the middle of the URL on trello, random letters and numbers
local trellokey = "(trellokey here)" --not required unless private board
local trellotoken = "(trello token here)" --ditto



local Group = 9390991 
local RequiredRank = 254 --Rank that can skip songs

local skipratio = 0.35

local songs = {}
local nowplaying = nil

local requests = {
}

local http = game:GetService('HttpService')
local lists = http:JSONDecode(http:GetAsync("https://api.trello.com/1/boards/"..trelloboard.."/lists?key="..trellokey.."&token="..trellotoken))
for _,v in pairs(lists) do
	if v.name == "Music List" then
		local items = http:JSONDecode(http:GetAsync("https://api.trello.com/1/lists/"..v.id.."/cards?key="..trellokey.."&token="..trellotoken))
		for _,v in pairs(items) do
			if v.name:match(":") ~= nil then
				local s,f = string.find(v.name,":")
				warn(string.sub(v.name,f+1))
				table.insert(songs, string.sub(v.name,f+1))
			end
		end
	end
end

function shuffleTable(t)
	math.randomseed(tick())
	assert(t, "shuffleTable() expected a table, got nil" )
	local iterations = #t
	local j
	for i = iterations, 2, -1 do
		j = math.random(i)
		t[i], t[j] = t[j], t[i]
	end
end

shuffleTable(songs)

local songnum = 0

function game.ReplicatedStorage.musicEvents.getSong.OnServerInvoke()
	if nowplaying then
		return game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name
	else
		return nil
	end
end

game.ReplicatedStorage.musicEvents.purchaseSong.OnServerEvent:connect(function(p)
	if p.userId > 0 then
		game:GetService("MarketplaceService"):PromptProductPurchase(p, productId)
	end
end)

local votes = {
	
}

function makesong()
	workspace:WaitForChild("speaker"):WaitForChild("Sound"):Stop()
	wait()
	if #requests == 0 then
		songnum = songnum+1
		if songnum > #songs then
			songnum = 1
		end
		nowplaying = songs[songnum]
	else
		nowplaying = requests[1]
		table.remove(requests,1)
	end
	local thisfunctionssong = nowplaying
	workspace.speaker.Sound.SoundId = "rbxassetid://"..thisfunctionssong
	wait()
	workspace.speaker.Sound:Play()
	game.ReplicatedStorage.musicEvents.newSong:FireAllClients(game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name)
	votes = {}
	wait(120)
	if "rbxassetid://"..nowplaying == "rbxassetid://"..thisfunctionssong then
		makesong()
	end
end

function countVotes()
	local c = 0
	for _,v in pairs(votes) do
		if v[2] == true then
			c = c +1
		end
	end
	local remainder = #game.Players:GetPlayers() - #votes
	local percent = (c + (remainder/2))/#game.Players:GetPlayers()
	game.ReplicatedStorage.musicEvents.voteChange:FireAllClients(percent)
	if percent <= skipratio then
		--skip song
		makesong()
	end
	return
end

game.ReplicatedStorage.musicEvents.voteYes.OnServerEvent:connect(function(p)
	for _,v in pairs(votes) do
		if v[1] == p.Name then
			v[2] = true
			countVotes()
			return
		end
	end
	table.insert(votes, {p.Name, true})
	countVotes()
end)

game.ReplicatedStorage.musicEvents.voteNo.OnServerEvent:connect(function(p)
	for _,v in pairs(votes) do
		if v[1] == p.Name then
			v[2] = false
			countVotes()
			return
		end
	end
	table.insert(votes, {p.Name, false})
	countVotes()
end)


game.Players.PlayerAdded:connect(function(Player)
	Player.Chatted:connect(function(msg)
		if Player:GetRankInGroup(Group) >= RequiredRank then
			if msg == 'skipsong'or msg == 'skip song' or msg == 'skip' then
				makesong()
			end
		end
	end)
end)

game:GetService('MarketplaceService').ProcessReceipt = function(details)
	for _, player in ipairs(game.Players:GetPlayers()) do
		if player.userId == details.PlayerId then
            if details.ProductId == productId then
				game.ReplicatedStorage.musicEvents.addSong:FireClient(player)
				return Enum.ProductPurchaseDecision.PurchaseGranted
            end
        end	
    end
end

game.ReplicatedStorage.musicEvents.addSong.OnServerEvent:connect(function(p,id)
	if tonumber(id) ~= nil and game:GetService("MarketplaceService"):GetProductInfo(tonumber(id)).AssetTypeId == 3 then
		table.insert(requests, id)
	end
end)

makesong()

Are the quotation marks meant to be on the outside?

Yes, in the real script, it is actually pasted without the quotation marks but for security reasons I removed them from here.

Hey, I’m assuming you didn’t attach the whole script or smthn but the line getting the error is line 127, but in the script, line 127 is return

Could you either send the script again or send the contents of line 127?

Thanks!

Here is the contents of line 127:

workspace.speaker.Sound.SoundId = "rbxassetid://"..thisfunctionssong

okay, here’s your makesong() function

function makesong()
	if #requests > 0 or #songs > 0 then
		workspace:WaitForChild("speaker"):WaitForChild("Sound"):Stop()
		wait()
		if #requests == 0 then
			songnum = songnum+1
			if songnum > #songs then
				songnum = 1
			end
			nowplaying = songs[songnum]
			print(songs)
		else
			print(requests)
			nowplaying = requests[1]
			table.remove(requests,1)
		end
		local thisfunctionssong = nowplaying
		workspace.speaker.Sound.SoundId = "rbxassetid://"..thisfunctionssong
		wait()
		workspace.speaker.Sound:Play()
		game.ReplicatedStorage.musicEvents.newSong:FireAllClients(game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name)
		votes = {}
		wait(120)
		if "rbxassetid://"..nowplaying == "rbxassetid://"..thisfunctionssong then
			makesong()
		end
	end
end

This way it won’t throw errors when you don’t have any songs listed, so add songs before you try to run the function :slight_smile:

Allow me a moment to ensure this works.

1 Like

oh, also the for loop above the function shuffleTable(t)

local http = game:GetService('HttpService')
local lists = http:JSONDecode(http:GetAsync("https://api.trello.com/1/boards/"..trelloboard.."/lists?key="..trellokey.."&token="..trellotoken))
for _,v in pairs(lists) do
    if v.name == "Music" then
    	local items = http:JSONDecode(http:GetAsync("https://api.trello.com/1/lists/"..v.id.."/cards?key="..trellokey.."&token="..trellotoken))
		for _,v in pairs(items) do
			if v.name:match(":") ~= nil then
				local s,f = string.find(v.name,":")
				-- warn(string.sub(v.name,f+1))
				table.insert(songs, string.sub(v.name,f+1))
			end
		end
	end
end

that should work now

1 Like

I ignore those. Are there genuine errors from the script?
If not, do you hear the songs you listed on the trello?

They are from the script and I do not hear the songs.

No, they’re Roblox sound errors. Those errors typically resolve themselves.

Anyways, try this:

function makesong()
	if #requests > 0 or #songs > 0 then
		workspace:WaitForChild("speaker"):WaitForChild("Sound"):Stop()
		wait()
		if #requests == 0 then
			songnum = songnum+1
			if songnum > #songs then
				songnum = 1
			end
			nowplaying = songs[songnum]
			print(songs)
		else
			print(requests)
			nowplaying = requests[1]
			table.remove(requests,1)
		end
		local thisfunctionssong = string.split(nowplaying,":")[2]
		workspace.speaker.Sound.SoundId = "rbxassetid://"..thisfunctionssong
		wait()
		workspace.speaker.Sound:Play()
		--game.ReplicatedStorage.musicEvents.newSong:FireAllClients(game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name)
		votes = {}
		wait(120)
		if "rbxassetid://"..nowplaying == "rbxassetid://"..thisfunctionssong then
			makesong()
		end
	end
end

It still isn’t working. There doesn’t appear to be any new errors.

Judging by the code given and error provided, either songs[songnum] is nil or requests[1] is nil (or both). The error implies that your variable thisfunctionssong is nil. If that’s the case, then we need to look at every line (prior to this one) that this variable’s value is changed. Fortunately, there is only one line to look at, and that is where you first created the variable with local thisfunctionssong = nowplaying. If thisfunctionssong is nil, and it is set by nowplaying, then nowplaying must also be nil. Now, we look at every line nowplaying is set or changed. Those lines would be these two lines:

-- This line
nowplaying = songs[songnum]
-- And this line
nowplaying = requests[1]

We now know that it must be either songs[songnum] or requests[1] that is nil (or both). Because they are in separate if statements, add print statements in both the if portion and the else portion to determine where the code went.

if #requests == 0 then
    ...
    nowplaying = songs[songnum]
    print("Reached if!")
else
    ...
    nowplaying = requests[1]
    print("Reached else!")
end

From here, you’ll easily be able to see where the error is. If, in the output, you see “Reached if!”, then that means nowplaying is set to songs[songnum] which in turn means that songs[songnum] is nil. If the output displays “Reached else!” then through the same logic requests[1] is nil. From here, you should try to figure out why those values are nil and that should help you figure out the problem.

Because both lines involve indexing a table (accessing a value in a table through its index), I would say that the it is likely that, if songs[songnum] is the problem, either songnum is not a valid index in songs or that songs is straight up empty. If requests[1] is the issue, it is likely that requests is empty. Similar to how I went about figuring out why thisfunctionssong was nil, you can try figuring out why your table values may be wrong.


An explanation about the error itself

The error you have, “attempt to concatenate string with nil,” is a very simple error. In the context of programming, string concatenation simply means the addition of two strings. In Lua, you can perform concatenation with the .. operator, which is what you do. However, the full error says that you attempted to add a string with a nil value. This errors out because you are only allowed to concatenate strings with either other strings or with numbers. The solution is to turn nil into a string with the tostring() method. Your errored line of code would then turn into the following:

workspace.speaker.Sound.SoundId = "rbxassetid://" .. tostring(thisfunctionssong)

The tostring() method will turn anything you give it into a string, which then means that your line of code is guaranteed to be concatenating two strings all the time. This will help remove the error from output. Although it probably doesn’t solve the larger issue (that being your variable thisfunctionssong becoming nil), I hope it does help when you encounter future attempt to concatenate string with xx errors.

Yeah, everything you said above is something any programmer who read the code would be able to figure in less time than reading your reply. Next time, please try to keep up to date and follow along with what people have previously tried in the replies?

Thanks :slight_smile:

Okay, I’m going to send you all of what I have (which is working)

--[[------------------
	How to use system.
	
	Step 1. Place 
	songlist --> ServerScriptService,
	MusicGui --> StarterGui,
	musicEvents --> ReplicatedStorage.
	speaker --> Workspace
	
	Step 2. Enter data below.
	
	Step 3. Enjoy!
	
	~Wizzy011
	
	SCRIPTING DONE BY JAY_VUL
------------------]]--

local productId = 0--your dev product for a song

local trelloboard = "" --the thing in the middle of the URL on trello, random letters and numbers
local trellokey = "" --not required unless private board
local trellotoken = "" --ditto



local Group = 0
local RequiredRank = 0--Rank that can skip songs

local skipratio = 0.35



























-- do not touch anything below or I will cry ~Wiz --
local songs = {}
local nowplaying = nil

local requests = {
}

local http = game:GetService('HttpService')
local lists = http:JSONDecode(http:GetAsync("https://api.trello.com/1/boards/"..trelloboard.."/lists?key="..trellokey.."&token="..trellotoken))

for _,v in pairs(lists) do
	if v.name == "Music" then
		local items = http:JSONDecode(http:GetAsync("https://api.trello.com/1/lists/"..v.id.."/cards?key="..trellokey.."&token="..trellotoken))
		for _,v in pairs(items) do
			if v.name:match(":") ~= nil then
				local s,f = string.find(v.name,":")
				--warn(string.sub(v.name,f+1))
				table.insert(songs, string.sub(v.name,f+1))
			end
		end
	end
end

function shuffleTable(t)
	math.randomseed(tick())
	assert(t, "shuffleTable() expected a table, got nil" )
	local iterations = #t
	local j
	for i = iterations, 2, -1 do
		j = math.random(i)
		t[i], t[j] = t[j], t[i]
	end
end

shuffleTable(songs)

local songnum = 0

--[[function game.ReplicatedStorage.musicEvents.getSong.OnServerInvoke()
	if nowplaying then
		return game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name
	else
		return nil
	end
end

game.ReplicatedStorage.musicEvents.purchaseSong.OnServerEvent:connect(function(p)
	if p.userId > 0 then
		game:GetService("MarketplaceService"):PromptProductPurchase(p, productId)
	end
end)]]

local votes = {

}

function makesong()
	if #requests > 0 or #songs > 0 then
		workspace:WaitForChild("speaker"):WaitForChild("Sound"):Stop()
		wait()
		if #requests == 0 then
			songnum = songnum+1
			if songnum > #songs then
				songnum = 1
			end
			nowplaying = songs[songnum]
		else
			nowplaying = requests[1]
			table.remove(requests,1)
		end
		local thisfunctionssong = string.split(nowplaying,":")[2]
		if thisfunctionssong == nil then return end
		workspace.speaker.Sound.SoundId = "rbxassetid://"..thisfunctionssong
		wait()
		workspace.speaker.Sound:Play()
		--game.ReplicatedStorage.musicEvents.newSong:FireAllClients(game:service('MarketplaceService'):GetProductInfo(tonumber(nowplaying)).Name)
		votes = {}
	end
end

function countVotes()
	local c = 0
	for _,v in pairs(votes) do
		if v[2] == true then
			c = c +1
		end
	end
	local remainder = #game.Players:GetPlayers() - #votes
	local percent = (c + (remainder/2))/#game.Players:GetPlayers()
	game.ReplicatedStorage.musicEvents.voteChange:FireAllClients(percent)
	if percent <= skipratio then
		--skip song
		makesong()
	end
	return
end
--[[
game.ReplicatedStorage.musicEvents.voteYes.OnServerEvent:connect(function(p)
	for _,v in pairs(votes) do
		if v[1] == p.Name then
			v[2] = true
			countVotes()
			return
		end
	end
	table.insert(votes, {p.Name, true})
	countVotes()
end)

game.ReplicatedStorage.musicEvents.voteNo.OnServerEvent:connect(function(p)
	for _,v in pairs(votes) do
		if v[1] == p.Name then
			v[2] = false
			countVotes()
			return
		end
	end
	table.insert(votes, {p.Name, false})
	countVotes()
end)]]


game.Players.PlayerAdded:connect(function(Player)
	Player.Chatted:connect(function(msg)
		if Player:GetRankInGroup(Group) >= RequiredRank then
			if msg == 'skipsong'or msg == 'skip song' or msg == 'skip' then
				makesong()
			end
		end
	end)
end)
--[[
game:GetService('MarketplaceService').ProcessReceipt = function(details)
	for _, player in ipairs(game.Players:GetPlayers()) do
		if player.userId == details.PlayerId then
			if details.ProductId == productId then
				game.ReplicatedStorage.musicEvents.addSong:FireClient(player)
				return Enum.ProductPurchaseDecision.PurchaseGranted
			end
		end	
	end
end

game.ReplicatedStorage.musicEvents.addSong.OnServerEvent:connect(function(p,id)
	if tonumber(id) ~= nil and game:GetService("MarketplaceService"):GetProductInfo(tonumber(id)).AssetTypeId == 3 then
		table.insert(requests, id)
	end
end)]]

wait(5)

while wait(0.1) do
	pcall(function()
		if workspace:WaitForChild("speaker"):WaitForChild("Sound").IsPlaying == false then
			makesong()
		end
	end)
end

Also, can you remove the songs in your trello that have been moderated?


That is the cause to that problem :slight_smile:

In case you didn’t know, there’s a lot of very young programmers on the devforum. That’s why I tried to be as specific as I could in my explanation. On the contrary, the solutions provided by others do not provide any explanation. Simply presenting code without any explanation of changes and reasoning of changes (along with a whopping count of 0 comments in it) does not solve the problem. It’s the equivalent of giving a fish to someone, as opposed to teaching them how to fish. Also, none of the solutions described the meaning of the error.

Okay. So then why would OP be asking for help? The answer is probably because they don’t know what the error means.

Okay, fair point. Though, you could still try to incorporate what other people have done to help in the replies.

I actually was going to and forgot to mention that other’s solutions may help solve the issue. My main gripe is that there were no explanations. I haven’t been on the devforum for as long as you have, but I’ve seen so many disappointing “solutions” that provide no explanations of code provided. Thanks for understanding.

1 Like