I'm trying to make a script where players are given no shirt and a certain pants ID the very first time they join the game, then when they buy a new shirt at the store it saves that they own that shirt and they spawn with that shirt, even if they leave the game. However, my script is outputting errors.

15:44:33.501 - ServerScriptService.PoorClothes:11: attempt to index field 'sessionData' (a nil value)

I'm also getting an error with SetStat but I couldn't get that one copy pasted

ModuleScript named PlayerStatManager

-- Setup table that we will return to scripts that require the ModuleScript.
local PlayerStatManager = {}
 
-- Create variable for the DataStore.
local DataStoreService = game:GetService('DataStoreService')
local playerData = DataStoreService:GetDataStore('PlayerData')
 
-- Create variable to configure how often the game autosaves the player data.
local AUTOSAVE_INTERVAL = 60

local DATASTORE_RETRIES = 3
 
-- Table to hold all of the player information for the current session.
local sessionData = {}
 
-- Function the other scripts in our game can call to change a player's stats. This
-- function is stored in the returned table so external scripts can use it.
function PlayerStatManager:ChangeStat(player, statName, changeValue)
	sessionData[player][statName] = sessionData[player][statName] + changeValue
end

local function dataStoreRetry(dataStoreFunction)
	local tries = 0	
	local success = true
	local data = nil
	repeat
		tries = tries + 1
		success = pcall(function() data = dataStoreFunction() end)
		if not success then wait(1) end
	until tries == DATASTORE_RETRIES or success
	if not success then
		error('Could not access DataStore! Warn players that their data might not get saved!')
	end
	return success, data
end
 
-- Function to retrieve player's data from the DataStore.
local function getPlayerData(player)
	return dataStoreRetry(function()
		return playerData:GetAsync(player.UserId)
	end)end
 
-- Function to save player's data to the DataStore.
local function savePlayerData(player)
	if sessionData[player] then
		return dataStoreRetry(function()
			return playerData:SetAsync(player.UserId, sessionData[player])
		end)
	end
end
 
-- Function to add player to the sessionData table. First check if the player has
-- data in the DataStore. If so, we'll use that. If not, we'll add the player to
-- the DataStore.
local function setupPlayerData(player)
	local success, data = getPlayerData(player)
	if not success then
		-- Could not access DataStore, set session data for player to false.
		sessionData[player] = false
	else
		if not data then
			-- DataStores are working, but no data for this player
			sessionData[player] = {Shirt = "1", Pants = "624636052"}
			savePlayerData(player)
		else
			-- DataStores are working and we got data for this player
			sessionData[player] = data
		end
	end	
end
 
-- Function to run in the background to periodically save player's data.
local function autosave()
	while wait(AUTOSAVE_INTERVAL) do
		for player, data in pairs(sessionData) do
			savePlayerData(player)
		end
	end
end
 
-- Bind setupPlayerData to PlayerAdded to call it when player joins.
game.Players.PlayerAdded:connect(setupPlayerData)
 
-- Call savePlayerData on PlayerRemoving to save player data when they leave.
-- Also delete the player from the sessionData, as the player isn't in-game anymore.
game.Players.PlayerRemoving:connect(function(player)
	savePlayerData(player)
	sessionData[player] = nil
end)
 
-- Start running autosave function in the background.
spawn(autosave)
 
-- Return the PlayerStatManager table to external scripts can access it.
return PlayerStatManager

Saving script

-- Require ModuleScript so we can change player stats
local PlayerStatManager = require(game.ServerStorage.PlayerStatManager)
 
-- After player joins we'll periodically check and save their clothes
game.Players.PlayerAdded:connect(function(player)
	while wait(2) do
		local shirt = game.Workspace[player.Name].Shirt.ShirtTemplate:sub(14)
		local pants = game.Workspace[player.Name].Pants.PantsTemplate:sub(14)
		PlayerStatManager:SetStat(player, 'Shirt', shirt)
		PlayerStatManager:SetStat(player, 'Pants', pants)
	end
end)

Clothing updater script

local PlayerStatManager = require(game.ServerStorage.PlayerStatManager)

game.Players.PlayerAdded:connect(function(player)
	player.CharacterAdded:connect(function(character)	
		if character:findFirstChild("Shirt") ~= nil then
			character.Shirt.ShirtTemplate = "rbxassetid://" .. PlayerStatManager.sessionData[player].Shirt
		else
			local newshirt = Instance.new("Shirt")
			newshirt.Parent = character
			newshirt.Name = "Shirt"
			newshirt.ShirtTemplate = "rbxassetid://" .. PlayerStatManager.sessionData[player].Shirt
		end
		if character:findFirstChild("Pants") ~= nil then
			character.Pants.PantsTemplate = "rbxassetid://" .. PlayerStatManager.sessionData[player].Pants
		else
			local newPants = Instance.new("Pants")
			newPants.Parent = character
			newPants.Name = "Pants"
			newPants.PantsTemplate = "rbxassetid://" .. PlayerStatManager.sessionData[player].Pants
		end
	end)
end)