Code warns me of an infinite yield for in-scope variable but not for upvalue?

I work with Aero Game Framework and I’ve encountered an issue that I can’t quite understand. My code warns me that an infinite yield has been detected if I use an in-scope variable but not for an upvalue.

In Aero, each service has an Init method. This method is called when the internal bootstrapper sets things up and is ready to run through each service. Since I don’t use ServerScriptService except to fetch the ChatServiceRunner, I decided to move it into my Init function.

-- Barebones excerpt of my code
function ChatSetupService:Init()
    local ServerScriptService = game:GetService("ServerScriptService")

    -- Other setup code here

    local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
end

For some reason, setting up my function like this warns me of an infinite yield. On the other hand, if I define ServerScriptService outside of the function, that isn’t the case.

-- Barebones excerpt of my code, once again
local ServerScriptService = game:GetService("ServerScriptService")

-- Other code here: adding methods, other constants and variables, so on.

function ChatServiceSetup:Init()
    local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
end

Is anyone able to explain the behaviour behind this? I wanted to remove the ServerScriptService constant as an upvalue to avoid keeping a reference when I don’t use it except for this one time, but the warning turns me away from doing so.

2 Likes

I can’t replicate your issue. This is how my code has been set up to try to reproduce your issue.

local TestService = {Client = {}}


function TestService:Init()
	local ServerScriptService = game:GetService("ServerScriptService")
	local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
	print(ChatService.GetSpeaker)
end

return TestService

Output:
--> function: ...

Is there anything I’m missing here?

Could I have some more information on your repro?

  • How did your console look?
  • What view were you looking from, server or client?
  • What testing method did you use?
    • Live server or Studio test? Which method (F5, F6, F7) if Studio tested?

For reference, this is what I’m seeing:

Edit: Console suddenly decides it doesn’t want to randomly warn me now? I’m getting sporadic behaviour right now, still don’t understand what’s wrong with perfectly fine code.

I tested in both studio and in-game; they both provide the same output.

Studio (Server)

Live

Have you updated AGF to it’s latest version?

Very odd behaviour.

Edit: I use “F5” to run in Studio

Aero Game Framework is at its latest version, except I use a modified version which ports the ServerStorage section to ServerScriptService. Shouldn’t change anything, especially since hierarchy is only relevant during bootstrapping.

Honestly I haven’t the slightest what’s happening. I know it’s not a bug and I goofed something in my implementation but I don’t understand what or why. ChatServiceRunner doesn’t get injected late enough for WaitForChild to warn me that an infinite yield is possible.

Could you elaborate on this? Have you modified the “AeroServer” Module to do this?

You know how when you install Aero Game Framework, you receive two folders in each respective server container? ServerStorage and ServerScriptService.

ServerScriptService
    Aero
        Internal
            AeroServer
ServerStorage
    Aero
        Modules
        Services
        version

I moved the Modules and Services folders from ServerStorage.Aero to ServerScriptService.Aero and deleted the empty ServerStorage folder along with the version ValueObject. Hierarchy changes to this:

ServerScriptService
    Aero
        Internal
        Modules
        Services

The only modification I made to the server bootstrapper is where it fetches its server-side components from by changing GetService(“ServerStorage”) to GetService(“ServerScriptService”).

The only possible explanation I can give is that somehow the code is somehow being run locally (extremely unlikely), or the Module is indeed taking a very long time to load.

Result with Modified Hierarchy

Yield came from LocalScript

How consistently does the yield occur (like out of 10 tests or so)?

I have more faith in the latter circumstance than the former. LocalScripts will always warn you of infinite yields when you use WaitForChild on any server container as the service itself will exist but its contents will not as they aren’t replicated.

I can’t get accurate results for that kind of a test because it seems to be intermittently happening now.

I’m going to mark this as the solution for now. It’s a complete assumption but I believe longer load time as a probable cause than anything and this problem’s generating an unneeded headache.