Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Table expected, got nil & Attempt to index upvalue (a nil value)?

So, I'm trying to save a Table using DataStore. It's coming up with 2 errors. I'm trying to print every value inside of the table and it's giving me this error

16:26:55.044 - ServerScriptService.Script:16: bad argument #1 to 'pairs' (table expected, got nil)

16:26:55.044 - Stack Begin

16:26:55.044 - Script 'ServerScriptService.Script', Line 16

16:26:55.045 - Stack End

And everytime I exit my test in studio, or in a live server, it gives me this error when I'm trying to save my table.

16:26:56.480 - ServerScriptService.Script:25: attempt to index upvalue 'testList' (a nil value)

This is the ServerScript inside of ServerScriptService

local testList = {33788911}
local testStore = game:GetService("DataStoreService"):GetDataStore("TestStore")

game.Players.PlayerAdded:Connect(function(player)
	local success,errorMessage = pcall(function()
		newList = testStore:GetAsync("testData-KB")
	end)
	
	if success then
		testList = newList
		print("Test Data Was Loaded!")
	else
		warn(errorMessage.." | There Was An Error Loading Test Data!")
	end
	
	for _,p_ID in pairs(testList) do
		if player.UserId == p_ID then
			print("Special Player "..player.Name.." Has Arrived!")
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errorMessage = pcall(function()
		testList:SetAsync("testData-KB",testList)
	end)
	
	if success then
		print("Test Data Was Saved!")
	else
		warn(errorMessage.." | There Was An Error In Saving The Test Data!")
	end
end)

I'm not sure if I've formatted something wrong or if I just did this wrong in general.

2 answers

✓ Accepted answer

There are quite a lot of errors here. I'll give you a list of each and how to fix them.

  1. You have to remember to make an actual variable for variables you're giving values too. In this case, you didn't set the value for 'newList' when you were giving it a value (if data was found). The reason you weren't getting an error for that is because the data was returning nil because nothing was being saved in the first place. I'll get into that part later though.

To fix this, you simply need to make the variable first.

game.Players.PlayerAdded:Connect(function(plr)

	local NewList --New Variable

	local success, err = pcall(function()
		NewList = testStore:GetAsync('testData-KB')
	end)


	if NewList and type(NewList) == 'table' then else return end --ends the function if data was not found or the data was not a table
end

Also, I would recommend using function based variables for datastores. In yours you used a script wide variable 'TestList' accessible by all the functions. Which can easily cause data errors. So instead, put that variable inside the PlayerAdded function.

game.Players.PlayerAdded:Connect(function(plr)

	local NewList

	local TestList  = {} --Inside the function

	local success, err = pcall(function()
		NewList = testStore:GetAsync('testData-KB')
	end)


	if NewList then else return end
	
	if success then
		TestList = NewList
		print('Test Data Found')
	else
		warn('There was an error finding Test Data for '..plr.Name)
	end

end

However after looking at the rest of your script, you clearly want it to say that a player has entered the game if their user ID is found. So just include a separate table with the UserID's you want, then go through that with a for loop. Like this

local IDs = {1111} -- (player id you want to check)

for i, v in pairs(IDs) do
	if plr.UserId == v then
		print(plr.Name..' has joined the game!')
	end
end
  1. When the player leaves the game, you aren't actually saving any data.

You did 'testList:SetAsync' which wouldn't do anything, since testList is a table and not a DataStore. I think what you meant to do is something like this...

game.Players.PlayerRemoving:Connect(function(plr)
	local PlayerData = testData:GetAsync('testData-KB')

	if PlayerData and type(PlayerData) == 'table' then
		testData:SetAsync('testData-KB', PlayerData)
	else
		warn('Failed to save data for '..plr.Name)
	end
end

What it looks like you're trying to do here is just print something when a certain player joins the game. You don't need datastores to do this. All you need to do is something like this

local SpecialList = {19034023, 23049023, 32949205} --random ID's of the players you want announced when they join

game.Players.PlayerAdded:Connect(function(plr)
	for i, v in pairs(SpecialList) do
		if v == plr.UserId then
			print('The special '..plr.Name..' has joined the server!')
		end
	end
end

If this doesn't make sense to you, try looking more at DataStores here

1 comment

0

Thanks too! Your's was just a bit more detailed

First error: Global variable testlist got changed to nil on line 10 because new data defaults to nil.

Second error: as mentioned in the first error, since you changed a global testlist to nil. So that error occurred as well.

I'd recommend to check if the value is nil or not.

if not testlist then
	testlist={}; -- this is a replacement value.
end;

1 comment

0

Thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.