This is a change between 2.0 and 2.1.
In a number of my mods, I use a mechanism where I dynamically load files based on the presence of other mods. The relevant code is here: https://github.com/hgschmie/factorio-co ... r-mods.lua
When I install two of my mods that use this mechanism, I get an error at startup that one mod (ltn-train-info) tries to load files from the load path of the other (inventory-sensor-improved):
This has worked flawlessly under 2.0. Those mods have been "ported" by replacing "factorio version 2.0" with 'factorio version 2.1" and upgrading the mod version in info.json.
How to reproduce:
- disable all mods, keep only the base game
- install https://mods.factorio.com/mod/inventory-sensor-improved
- install https://mods.factorio.com/mod/ltn-train-info (this also installs LogisticTrainNetwork)
get the error at the next restart.
Logfile attached
[2.1.7] mod load path caching problems?
[2.1.7] mod load path caching problems?
- Attachments
-
- factorio-current.log
- (4.67 KiB) Downloaded 12 times
-
justarandomgeek
- Filter Inserter

- Posts: 314
- Joined: Fri Mar 18, 2016 4:34 pm
- Contact:
Re: [2.1.7] mod load path caching problems?
in inventory sensor data-updates, you do:
`lib.init` resolves correctly but is already cached from your earlier call in data, so it does nothing, and you discard the returned reference. You then call into the global var Framework, which was last touched by ltn-train-info, and thus has functions from there.
Code: Select all
require('lib.init')
Framework.post_data_updates_stage()
Re: [2.1.7] mod load path caching problems?
Thank you for looking into this! Why did that work in 2.0?justarandomgeek wrote: Thu Jun 25, 2026 10:52 pm in inventory sensor data-updates, you do:`lib.init` resolves correctly but is already cached from your earlier call in data, so it does nothing, and you discard the returned reference. You then call into the global var Framework, which was last touched by ltn-train-info, and thus has functions from there.Code: Select all
require('lib.init') Framework.post_data_updates_stage()
I (naively obviously) assumed that globals are still "per-mod" (similar to 'storage'). So I guess that is not true.
-
justarandomgeek
- Filter Inserter

- Posts: 314
- Joined: Fri Mar 18, 2016 4:34 pm
- Contact:
Re: [2.1.7] mod load path caching problems?
in 2.0 the package.loaded cache got reset to an earlier state between each top level data stage file, it appears this is no longer the case and it is now more like normal require caching behavior (the main deviation from upstream behavior now is the use of resolved name rather than requested name for the cache - which is necessary because we're all sharing one VM for data)
Re: [2.1.7] mod load path caching problems?
If you don't want to dig into mods but use a smaller reproducer, use the two attached mods.
- Attachments
-
- mod2_1.0.0.zip
- (1.56 KiB) Downloaded 14 times
-
- mod1_1.0.0.zip
- (1.56 KiB) Downloaded 13 times
-
justarandomgeek
- Filter Inserter

- Posts: 314
- Joined: Fri Mar 18, 2016 4:34 pm
- Contact:
Re: [2.1.7] mod load path caching problems?
i said this on discord yesterday, but just to have it on the record here in the thread: my conclusion is that require is working as intended and that this was a bug in the mod lua that had merely been hidden by previous quirks of loading that no longer apply, and that the fix is for the mod lua to use the value returned from require, which is linked up correctly, instead of the global variable that gets clobbered.
Re: [2.1.7] mod load path caching problems?
I resolved this and my takeaway is “don’t add a metatable to a global object”.
I moved everything inside my code to be locals and only expose as globals when I require my code in (by returning a function which can return multiple values) and then do
GlobalA, GlobalB = require(‘my-code’)()
Sure, it might be a lurking bug that happened to work in 2.0 but the changes for mod loading in 2.1 are there and they were not documented in the release notes so it bit me.
It’s a practical application of Hyrum’s law after all.
I moved everything inside my code to be locals and only expose as globals when I require my code in (by returning a function which can return multiple values) and then do
GlobalA, GlobalB = require(‘my-code’)()
Sure, it might be a lurking bug that happened to work in 2.0 but the changes for mod loading in 2.1 are there and they were not documented in the release notes so it bit me.
It’s a practical application of Hyrum’s law after all.
