ContentProvider:PreloadAsync() yielding forever without a response

Hey devs,

Today I encountered an issue when I was using ContentProvider:PreloadAsync() to preload animations for the game. It never gave a response, no errors, no messages of succeeding, nothing at all.

Here is the related code snippet:

local CP = game:GetService("ContentProvider")
local Debris = game:GetService("Debris")

CP.AssetFetchFailed:Connect(function(assetId)
	warn("AssetFetchFailed: "..assetId)
end)

local modules = {} :: {[string]: {string}} do
	for i, v in script:GetChildren() do
		if v:IsA("ModuleScript") then
			modules[v.Name] = require(v)
		end
	end
end

local toLoadAssets = {} do
	for category, items in pairs(modules) do
		for _, assetId in items do
			if category == "Animation" then
				local anim = Instance.new("Animation")
				anim.AnimationId = assetId
				
				table.insert(toLoadAssets, assetId)
			end
		end 
	end
end

print(toLoadAssets)
local startTime = os.clock()
CP:PreloadAsync(toLoadAssets, function(assetId, status)
	print("PreloadAsync() resolved asset ID:", assetId)
	print("PreloadAsync() final AssetFetchStatus:", status)
end)
print("Assets preloading completed. Time used: "..os.clock() - startTime)

I was trying to preload animations, it seemingly stuck without printing anything.
Are animations incompatible with ContentProvider:PreloadAsync() or something else?

Any help is appreciated!

1 Like

Hi there, try adding print statements throughout your code to try and see where it gets stuck.

1 Like

The print statement right before the PreloadAsync prints normally, but not the statements after it

1 Like

The issue isn’t that animations are incompatible with ContentProvider:PreloadAsync(). They can be preloaded, but only if you pass in instances, not just asset ID strings.

In your code you do this:
table.insert(toLoadAssets, assetId)

That means toLoadAssets ends up being a list of strings like "rbxassetid://1234567890".
But PreloadAsync ignores plain strings, it only works on Instance objects (e.g., Animation, Decal, Texture, MeshPart, etc.), or a table containing them.

Roblox Docs

You’re already creating Animation instances here:

local anim = Instance.new("Animation")
anim.AnimationId = assetId

But you never use them. Instead of pushing the assetId string, push the anim instance:

table.insert(toLoadAssets, anim)

So your toLoadAssets becomes a list of Animation objects, which PreloadAsync will correctly process.

Here is the full fixed code. Hopefully this work

local toLoadAssets = {} do
	for category, items in pairs(modules) do
		for _, assetId in items do
			if category == "Animation" then
				local anim = Instance.new("Animation")
				anim.AnimationId = assetId
				
				table.insert(toLoadAssets, anim) -- use the instance, not the string
			end
		end 
	end
end

print(toLoadAssets)
local startTime = os.clock()
CP:PreloadAsync(toLoadAssets, function(asset, status)
	print("PreloadAsync() resolved asset:", asset)
	print("PreloadAsync() final AssetFetchStatus:", status)
end)
print("Assets preloading completed. Time used: "..os.clock() - startTime)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.