This is just a repost from the scripters forum, but don't worry the few things that got tagged don't have any relevance to the problem

So basically, I have an inventory system saved as a table with tables inside of it, like categories for different items. Like one would be hats, or cosmetics, weapons, taunts, potions, etc. I'm currently making the inventory gui and trying to make the different categories appear when you select them in a drop down bar in the inventory gui. I'm getting an error that says the table is nil. The actual inventory isn't nil, but the categories inside of it that are also tables are nil.

-- the script inside of the drop down menu, inside the button that says cosmetics
-- also the reason this is so buggy and random is because I was trying to debug it for a while

script.Parent.MouseButton1Click:Connect(function()
	--fetching tables
	local datastore = game:GetService("DataStoreService"):GetDataStore(player.UserId)
	
	local pInv = datastore:GetAsync(player.UserId.."_inventory")
	
	if not pInv or pInv == nil then
		local pInv = module.getInventory()
		print("doingok1")
		repeat wait() until pInv ~= nil
		print("doingok2")
		datastore:SetAsync(player.UserId.."_inventory", pInv)
	end
	
	print("doingok3")
	--local pFolder = module.tableFind(pInv,'Cosmetics','yNC9d8aym')
	local pFolder = pInv
	print("doingok4")
	-- creating visuals
	
	for pos,value in pairs(pFolder.Cosmetics) do -- the error, says "bad argument to pairs, table expected, got nil"
		-- pos: name or place of the value
		-- value: value of the pos
		
		local visualC = thisFolder.main.CloneItem:Clone()
		visualC.Parent = thisFolder.main
		thisFolder.main.LastPos.Value = thisFolder.main.LastPos.Value + 1
		if thisFolder.main.LastPos.Value == 4 then
			thisFolder.main.LastRow.Value = thisFolder.main.LastRow.Value + 1
			thisFolder.main.LastPos.Value = 0
#	#e######v###################Dim2.new(0,125 * thisFolder.main.LastPos.Value + 25,0,105 * thisFolder.main.LastRow.Value + 5)
		local indexValue = game.ServerStorage.inventoryIndex(value.indexPos.category)
		indexValue = indexValue(value.indexPos.iName)
		visualC.ItemName.Text = indexValue.iName.Value
		visualC.ItemImage.Image = indexValue.Image.Value
		visualC.indexPos.Value = indexValue
	end
	
	
	
end)

And for those of you that want to know, here's the module that returns a new inventory for players that don't have one

function module.getInventory(object)
	
	local inv = {
		
		Loadouts = {
			
		    Garry = {
				Weapon = 'Stock';
				Cosmetic1 = nil;
				Cosmetic2 = nil;
				Outfit = nil;
				Ammount = 1;
				
		    };--Garry
		
			Ivy = {
				Weapon = 'Stock';
				Cosmetic1 = nil;
				Cosmetic2 = nil;
				Outfit = nil;
				Ammount = 1;
				
				
			};--Ivy
			
			Trainer = {
				Weapon = 'Stock';
				Cosmetic1 = nil;
				Cosmetic2 = nil;
				Outfit = nil;
				Ammount = 1;
				
			};--Trainer
			
		}; --Loadouts
		
		Cosmetics = {
			
			PremiumHat = {
				Quality = {
					q1## #C#########					q2 = "None";
				}; -- Rarity, and what effect it has if mythical.
				indexPos = {category = 'Cosmetics',iName = 'PremiumHat'};
				Ammount = 1;
				Archivable = false; -- can't trade, sell, or craft ( added later )
			}; -- Hat you get for becoming premium, given because the player has bought early access ( will be removed later )
			
		};
		
		Taunts = {
			
			FakeDeath = {
				indexPos = {category = 'Taunts',iName = 'FakeDeath'};
				Ammount = 1;
				Archivable = false;
				
			};
			
		};
		
		Potions = {
			
			FlamePotion = {
				
				indexPos = {category = 'Potions',iName = 'FlamePotion'};
				Amount = 1;
				Archivable = false;
				
			};
			
		};
		
		Equipment = {
			
			EnergyDrink = {
				
				indexPos = {category = 'Equipment',iName = 'FlamePotion'};
				Amount = 1;
				Archivable = false;
				
			};
			
		};
		
		Other = {
			
		};
		
	}--Inventory
	
	if object == "None" or object == nil then
		return inv
	else
		return inv(object)
	end
end 

######(edited - 00:25 11/6/17 for formatting)