Some problems with OS scripts

I am trying to simulate a functional OS in roblox with a file system and I am running into a weird issue:

Script #1 (directory hierarchy)

local dirHierarchy = {}

local player = game:GetService("Players").LocalPlayer
local FS = require(player.PlayerGui.FileSystem.FileSystem)

local NotesApp = require(script.Parent.AppHierarchy.NotesApp)
local DE = require(script.Parent.GUI.DesktopEnvironmentHandler)

function dirHierarchy.createDefaults()
	-- Desktop Environment Directory Structure
	FS.mkdir("Root", "System")
	FS.mkdir("Root/System", "GUI")
	FS.mkdir("Root/System/GUI", "DesktopEnvironment")
	
	-- Apps Directory structure
	FS.mkdir("Root/System", "Apps")
	-- Notes app
	FS.mkdir("Root/System/Apps", "Notes") -- Notes structure
	NotesApp.CreateAppContent()
	
	-- Desktop Environment files
	FS.mkdir("Root/System/GUI/DesktopEnvironment", "Wallpaper")
	DE.desktopWallpaperSet()
	task.wait(0.01)
	FS.mkdir("Root/System/GUI/DesktopEnvironment", "Taskbar")
	DE.taskbarCreate()
end

return dirHierarchy

Script #2 (DE handler)

local DE = {}

local player = game:GetService("Players").LocalPlayer
local FS = require(player.PlayerGui.FileSystem.FileSystem)
local SetWallpaper = require(script.SetWallapper)
local SetTaskbar = require(script.SetTaskbar)

function DE.desktopWallpaperSet()
	SetWallpaper.SetWallpaperId("rbxassetid://85415286398367")
end

function DE.taskbarCreate()
	SetTaskbar.createTaskbarFiles()
end

return DE

Script #3 (Set Wallpaper)

local setWallpaper = {}

local player = game:GetService("Players").LocalPlayer
local FS = require(player.PlayerGui.FileSystem.FileSystem)
local PM = require(player.PlayerGui.FileSystem.ProcessManager)

local wallpaperSetter = [[

local player = game:GetService("Players").LocalPlayer
local playerGui = player.PlayerGui
local playerScreen = playerGui.PlayerScreen

local FS = require(playerGui.FileSystem.FileSystem)

print("Executing")
local wallpaperImage = Instance.new("ImageLabel")
wallpaperImage.Name = "WallpaperImage"
wallpaperImage.Size = UDim2.fromScale(1, 1)
wallpaperImage.Position = UDim2.fromScale(0, 0)
wallpaperImage.Parent = playerScreen.DesktopEnvironment
wallpaperImage.ZIndex = 1

while true do
	wallpaperImage.Image = FS.read("Root/System/GUI/DesktopEnvironment/Wallpaper", "currentImage", "zimg")
	task.wait(1)
end

]]

function setWallpaper.SetWallpaperId(id: string)
	FS.write("Root/System/GUI/DesktopEnvironment/Wallpaper", "currentImage", "zimg", id)
	FS.write("Root/System/GUI/DesktopEnvironment/Wallpaper", "wallpaperSetter", "gui", wallpaperSetter)
	PM.run("Root/System/GUI/DesktopEnvironment/Wallpaper", "wallpaperSetter", "gui")
end

return setWallpaper

Script #4 (Set Taskbar)

local setTaskbar = {}

local player = game:GetService("Players").LocalPlayer
local FS = require(player.PlayerGui.FileSystem.FileSystem)
local PM = require(player.PlayerGui.FileSystem.ProcessManager)

local taskbarFrameScript = [[

print("Executing")
local player = game:GetService("Players").LocalPlayer
local playerGui = player.PlayerGui
local playerScreen = playerGui.PlayerScreen

local FS = require(playerGui.FileSystem.FileSystem)

local TaskbarFrame = Instance.new("Frame")
TaskbarFrame.Name = "TaskbarFrame"
TaskbarFrame.AnchorPoint = Vector2.new(0.5, 1)
TaskbarFrame.Position = UDim2.fromScale(0, 1)
TaskbarFrame.Size = UDim2.fromScale(1, 0.025)
TaskbarFrame.ZIndex = 2
TaskbarFrame.Parent = playerScreen.DesktopEnvironment

]]

function setTaskbar.createTaskbarFiles()
	FS.write("Root/System/GUI/DesktopEnvironment/Taskbar", "TaskbarFrame", "gui", taskbarFrameScript)
	print(FS.read("Root/System/GUI/DesktopEnvironment/Taskbar", "TaskbarFrame", "gui"))
	PM.run("Root/System/GUI/DesktopEnvironment/Taskbar", "TaskbarFrame", "gui")
end

return setTaskbar

Script #3 creates a working wallpaper and places it inside of the DesktopEnvironment folder
Script #4 is similar but it doesn’t seem to be able to create a taskbar inside of DesktopEnvironment and I have no idea why; If you’d like I could send over the PM and FS files right now

So the solution was simple:

Original PM:

local processManager = {}
processManager.processes = {}
local prc = processManager.processes

local processExecuter = require(script.Loadstring)
local errorManager = require(script.Parent.Parent.OSScripts.API.Abstractions.GUIOutputs.Error)
local fs = require(script.Parent.FileSystem)

function processManager.run(location: string, name: string, extension: string)
	local fileContent = fs.read(location, name, extension)
	if fileContent then
		local executable, failReason = processExecuter(fileContent)
		if executable then
			prc[location.."/"..name.."."..extension] = executable
			local success, errorMessage = pcall(function()
				prc[location.."/"..name.."."..extension]()
			end)

			if not success then
				errorManager.throwError("Error", "Failed to execute program: ".. errorMessage, 500, 250)
				return nil
			end
			
		else
			errorManager.throwError("Error", failReason, 500, 250)
		end
	else
		errorManager.throwError("Error", "Couldn't read file", 500, 250)
		return nil
	end
end

return processManager

the issue was that the while loop inside of the wallpaper was blocking the thread from executing the other script. Fixed by changing to:

local processManager = {}
processManager.processes = {}
local prc = processManager.processes

local processExecuter = require(script.Loadstring)
local errorManager = require(script.Parent.Parent.OSScripts.API.Abstractions.GUIOutputs.Error)
local fs = require(script.Parent.FileSystem)

function processManager.run(location: string, name: string, extension: string)
	local fileContent = fs.read(location, name, extension)
	if fileContent then
		local executable, failReason = processExecuter(fileContent)
		if executable then
			prc[location.."/"..name.."."..extension] = executable
			task.spawn(function()
				local success, errorMessage = pcall(function()
					prc[location.."/"..name.."."..extension]()
				end)

				if not success then
					errorManager.throwError("Error", "Failed to execute program: ".. errorMessage, 500, 250)
					return nil
				end
			end)
			
		else
			errorManager.throwError("Error", failReason, 500, 250)
		end
	else
		errorManager.throwError("Error", "Couldn't read file", 500, 250)
		return nil
	end
end

return processManager

Thanks to everyone who read this thread! Happy coding!