Skip to content

fix(ModuleLoader): an unparseable unmanaged module version failing the load - #45

Open
CoffeeFlux wants to merge 2 commits into
mainfrom
fix/unparseable-unmanaged-version
Open

CoffeeFlux wants to merge 2 commits into
mainfrom
fix/unparseable-unmanaged-version

Conversation

@CoffeeFlux

@CoffeeFlux CoffeeFlux commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Problem

When a required module returns a plain version value instead of a DepCtrl record, ModuleLoader.loadModules wraps that value in an unmanaged PackageRecord before it checks the version. If the value doesn't parse, the PackageRecord constructor asserts. The requiring script then fails with:

[DepCtrl] Bad DependencyControl record (Couldn't parse version number: Can't parse version string '##__LOG_VERSION__##'. ...)

The module never reaches the updater, so updating DepCtrl or the requiring script doesn't help. The only fix is deleting the file by hand.

This is what's behind TypesettingTools/Aegisub-Motion#94. The a-mo v1.1.0 release zip shipped untemplated, and a-mo.Log (a plain table with a string version) has been 1.0.0 since 2015, so a broken copy is never replaced. The zip has since been rebuilt, but existing installs stay broken. v0.6.3-alpha had the same assert, so this isn't a regression.

Change

  • In loadModules, an unmanaged version that doesn't parse is treated as 0.0.0. It fails any real requirement, so the module goes through the existing outdated-module update path (updater\require).
  • In formatVersionErrorTemplate, if that update fails (offline, no feed), the "Installed" value is shown verbatim instead of vnil.
  • Added tests for both, plus a changelog entry.

Trade-offs

  • A requirement of 0.0.0 (or a packed 0) is still satisfied by a module whose version doesn't parse, so such a module loads silently. It can't be worse than "any version".
  • An unmanaged module with a non-semver version (e.g. "1.2", "v1.0.0") that used to hard-fail will now be replaced from the requiring script's feed if one provides it. That's the same thing that already happens to an unmanaged module whose version is merely lower.
  • This only covers unmanaged modules. A managed module with a broken version asserts inside its own DependencyControl{} call while it's being required, and still surfaces as a module load error.

Testing

moonc -p passes on both changed files. I couldn't run the suite locally (missing Lua 5.1 rocks), so I'm relying on CI for that.

🤖 Generated with Claude Code

…e load

A required module that returns a plain version value instead of a DepCtrl
record is wrapped in an unmanaged record before its version is checked. When
that value doesn't parse, the record constructor asserts, so the requiring
script fails with "Bad DependencyControl record" and the module is never
offered to the updater. Nothing short of deleting the file recovers from it.

This shows up with Aegisub-Motion's a-mo.Log, whose v1.1.0 release zip shipped
with an untemplated "##__LOG_VERSION__##" version. a-mo.Log has been 1.0.0
since 2015, so no version bump ever replaces a broken copy.

Treat a version that doesn't parse as 0.0.0. It fails any real requirement,
so the module goes through the regular outdated-module update path. If that
update fails, the outdated message now shows the installed value verbatim
instead of "vnil".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Test results — macos-latest ✅1116 · ubuntu-latest ✅1116 · windows-latest ✅1113

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
3348 3345 0 3 0 0 1m 8s

🎉 No failed tests in this run.

Github Test Reporter by CTRF 💚

🔄 This comment has been updated

…on updater stub

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CoffeeFlux
CoffeeFlux requested a review from line0 October 7, 2026 17:48
@CoffeeFlux

Copy link
Copy Markdown
Member Author

I shipped a bad update, and it seems like the recovery path from that is harsher than I thought right now. This should make it possible for maintainers to bump a version and fix these sorts of issues, but needs to end up in a DepCtrl release. Sorry about the hassle.

@CoffeeFlux
CoffeeFlux force-pushed the fix/unparseable-unmanaged-version branch from 52e7919 to a078080 Compare October 7, 2026 18:06

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant