Skip to content

fix(mc-versions): support 26.2 and fix caches on macOS and Windows - #140

Merged
okafke merged 6 commits into
mainfrom
claude/github-issue-137-05c8df
Jul 14, 2026
Merged

fix(mc-versions): support 26.2 and fix caches on macOS and Windows#140
okafke merged 6 commits into
mainfrom
claude/github-issue-137-05c8df

Conversation

@ChipWolf

Copy link
Copy Markdown
Member

What

Rename the 26.2 module directory from 26.2 (with a dot) to 26_2 (underscore), and extend the README supported-versions range to 26.2.

Why

Fixes #137. Consumers running the action for MC 26.2 hit:

Error: Asset with name mc-runtime-test-26.2-*-neoforge-release.jar not found!

The 26.2 jars were never built or released. PR #138 added the module as a directory named 26.2 (with a dot), but:

  • the repo naming convention uses underscores (26_1, 1_21_11, …), and
  • ci-data.json correctly references "dir": "26_2".

So the CI build matrix produced a 26_2 entry pointing at a non-existent directory. The 26.2 build produced nothing, the release job had no 26.2 jars to attach, and the download failed. (Release 4.4.0 also predates #138 entirely.)

The fix

  • git mv 26.2 → 26_2 so the build matrix resolves. The build then produces mc-runtime-test-26.2-<apiver>-{lexforge,neoforge,fabric}-release.jar, exactly matching the downloader's mc-runtime-test-26.2-*-<loader>-release.jar pattern.
  • README: 26.1 - 26.1.226.1 - 26.2.

Verified

  • All ci-data.json build_data dirs now resolve on disk; the stale 26.2 dir is gone.
  • 26.2 has all three run entries (lexforge/neoforge/fabric).
  • 26_2/build.gradle (archivesName = mc-runtime-test, version = 26.2-<api>, classifier <platform>-release) yields precisely the expected jar names.

A full gradle build (Java 25 + Minecraft download) is CI-only and wasn't run locally.

Note for reviewer

This is a fix commit, so release-please will open a release PR on merge. Merging that release PR builds the now-working 26_2 module, publishes the 26.2 jars, and bumps action.yml's pinned tag: via its # x-release-please-version marker — so the pinned tag is intentionally left untouched here. Until that release lands, consumers should reference the action at @main.

🤖 Generated with Claude Code

ChipWolf added 2 commits July 12, 2026 22:38
PR #138 added the 26.2 module as a directory named `26.2` (with a dot),
but the repo naming convention uses underscores and `ci-data.json`
references `"dir": "26_2"`. The build matrix therefore pointed at a
non-existent `26_2` directory, so the 26.2 jars were never built or
attached to a release. Consumers hit:

    Asset with name mc-runtime-test-26.2-*-neoforge-release.jar not found!

Rename the directory to `26_2` so the build matrix resolves, the 26.2
artifacts are produced, and the next release-please release publishes
them. Also extend the README supported-versions range to 26.2.

Fixes #137
The 26.2 module's gradlew was committed by #138 with mode 100644
instead of 100755, so the CI build failed with:

    ./gradlew: Permission denied  (exit code 126)

Every other version's gradlew is 100755. Set the executable bit to match.
@okafke

okafke commented Jul 13, 2026

Copy link
Copy Markdown
Member

Ah this is a problem within HeadlessMc, the mc versions.json format changed as well as the way native libraries work.
I have been working on a new version of HeadlessMc which is not ready yet, but I will try to fix this in HeadlessMc 2.

@ChipWolf

Copy link
Copy Markdown
Member Author

Status of the red xvfb=false checks

The 26.2 build and the xvfb=true run-tests (the default path consumers use) pass for all three modloaders — this resolves the originally-reported Asset ... not found error in #137 once a release is cut.

The still-red checks are the xvfb=false / HeadlessMC --lwjgl runs. Those crash on 26.2 (all modloaders) with an upstream HeadlessMC bug, not anything in this repo:

java.lang.NullPointerException: ... "org.lwjgl.system.Configuration.SHARED_LIBRARY_EXTRACT_PATH" is null
	at com.mojang.blaze3d.platform.NativeLibrariesBootstrap.configureLWJGLLibraryPath

HeadlessMC's lwjgl agent guts org.lwjgl.system.Configuration's static initializer, leaving its option fields null; MC 26.2's new NativeLibrariesBootstrap reads one of them during native-library loading. 26.1.x is unaffected (it never read that field at bootstrap), which is why this was never seen before — and it only surfaced now because the 26.2-vs-26_2 directory mismatch meant 26.2 never actually ran in CI before this PR (PR #138's run-tests were all skipped).

Upstream fix: headlesshq/headlessmc#427. Once it's released, this repo can bump hmc-version in action.yml and the xvfb=false runs will go green. Until then these checks are expected to stay red rather than being muted.

@ChipWolf

Copy link
Copy Markdown
Member Author

Thanks @okafke, that matches what I traced: the --lwjgl agent guts org.lwjgl.system.Configuration's static initializer, so 26.2's new NativeLibrariesBootstrap NPEs reading SHARED_LIBRARY_EXTRACT_PATH (26.1.x never touched it at bootstrap, which is why only 26.2 breaks).

I opened headlesshq/headlessmc#427 as a minimal fix for the native-libraries crash on the current agent: leave org.lwjgl.system.Configuration untransformed (it's a pure settings registry with no native calls), so it behaves as it does in a real launch. It has a regression test and passed your build-java-8 CI.

Completely fine if you'd rather fold this into HeadlessMC 2 alongside the versions.json changes, that's your call, just flagging it in case a current-line patch is useful to unblock headless 26.2 sooner. Either way this PR's core fix (the 26_2 build + the default xvfb runs) stands, and the --lwjgl runs will go green once HeadlessMC ships the fix and we bump hmc-version.

🤖 Addressed by Claude Code

@ChipWolf

Copy link
Copy Markdown
Member Author

Correction on the upstream pointer: the canonical fix is headlesshq/headlessmc#426 (by @okafke), not the #427 I linked earlier — I'd missed #426 when I opened mine, so I've closed #427 in its favour.

#426 is the complete fix: it ignores org.lwjgl.system.Configuration (the native-libraries NPE) and also handles 26.2's new GPUDevice/DeviceLimits and related redirections. It already tests against this PR's branch (dir: 26_2, mc: 26.2). Once #426 ships in a HeadlessMC release, bumping hmc-version in action.yml here will turn the --lwjgl (xvfb=false) 26.2 runs green.

🤖 Addressed by Claude Code

@okafke

okafke commented Jul 13, 2026

Copy link
Copy Markdown
Member

Ok, the auto-release for HeadlessMc 2.10.0 is running and should fix this. I can finalize this release in about 3 hours. Please note my preference on adding Claude as co-author in headlesshq repositories (headlesshq/headlessmc#428 (comment)). Before this is merged I would like to force push to remove the co-author tag.

@ChipWolf
ChipWolf force-pushed the claude/github-issue-137-05c8df branch from 1c6c317 to 1508be0 Compare July 13, 2026 18:34
@ChipWolf

Copy link
Copy Markdown
Member Author

Understood, and noted for headlesshq repos. I've force-pushed this branch to drop the co-author trailer from the commits (Fixes #137 preserved). The upstream PaperMC fix landed via #429, and the HeadlessMc lwjgl 26.2 fix via #426, so once 2.10.0 is finalized I'll bump hmc-version in action.yml here to turn the remaining --lwjgl runs green.

@okafke

okafke commented Jul 13, 2026

Copy link
Copy Markdown
Member

Not 100% sure whats wrong here investigating, maybe the cache is broken.

@ChipWolf

Copy link
Copy Markdown
Member Author

Confirmed the cache theory. With HeadlessMc 2.10.0 the --lwjgl 26.2 runs now pass on ubuntu and windows; only the 3 macOS xvfb=false runs fail, and it's a stale cache, not a launch regression:

Cache hit for: 26.2-neoforge-hmc
Cache restored successfully
if [ ! -f "$HOME/.minecraft/versions/26.2/26.2.json" ]; then   # false → install skipped
Couldn't find object for regex '.*neoforge.*'!                 # exit 255

The macOS 26.2-*-hmc caches were populated on 2026-07-12 by the earlier pre-2.10.0 runs that crashed mid-install: they contain vanilla 26.2.json but no installed modloader version. The action's install guard only checks for the vanilla json, so it skips reinstalling, and the launch finds no modloader. Caches are partitioned by runner OS, so only macOS carries the poisoned copy.

Two ways to clear it:

  • Immediate: delete the stale caches and re-run the 3 macOS jobs — they'll repopulate against 2.10.0.
    gh cache delete 26.2-neoforge-hmc --repo headlesshq/mc-runtime-test
    gh cache delete 26.2-fabric-hmc   --repo headlesshq/mc-runtime-test
    gh cache delete 26.2-forge-hmc    --repo headlesshq/mc-runtime-test
    
  • Durable (optional): harden the install guard to check the modloader-installed version instead of just <mc>.json, or salt the cache key with hmc-version, so a partial cache self-heals rather than sticking.

@okafke

okafke commented Jul 13, 2026

Copy link
Copy Markdown
Member

Yeah we should maybe harden the cache at some point? not sure though

The cache key was <mc>-<modloader>-hmc, independent of the HeadlessMC
version. A partial .minecraft cached by an older HeadlessMC (e.g. one that
crashed mid modloader-install) kept being restored after upgrading, and
because the install guard only checks for the vanilla <mc>.json it skipped
reinstalling, so launch failed with 'Couldn't find object for regex ...'.

Salt the key with hmc-version so upgrading HeadlessMC busts stale caches
and repopulates .minecraft cleanly.
@ChipWolf

Copy link
Copy Markdown
Member Author

Went ahead and hardened it here (34e2279): the .minecraft cache key now includes hmc-version, so bumping HeadlessMc busts stale caches instead of restoring a partial .minecraft from an older, crashier build. That also unblocks the 3 macOS --lwjgl runs — the new 26.2-*-hmc-2.10.0 key misses the poisoned 26.2-*-hmc caches, so they reinstall cleanly against 2.10.0. The old caches are now orphaned and will age out on their own. If you'd rather not couple the key to the version, happy to drop it — but it's the minimal fix for exactly what bit us here.

@okafke

okafke commented Jul 14, 2026

Copy link
Copy Markdown
Member

That's not it. I don't think the cache action would cache if we have crashed mid install, it does not really make sense. I just thought long about it: The error is only on mac-os, I think the cache got restored from Ubuntu, to /home/runner/.minecraft, however, that's not where headlessmc thinks the .minecraft installation is, so it cannot find anything. I think similar things could happen if we restored a cache from mac-os to another OS. The reason we have not found out about this earlier is our rigorous caching, there probably have not been successful, cached, consecutive runs for the same mc version since we have added support for windows and macos.
Now some options that could maybe fix this:

  • set hmc.mcdir in the config.properties to a directory that is the same on windows/mac/ubuntu.
  • cache .minecraft with os name in the key? That is more caches, one per OS, but safest. There is also native libraries, so we will need one cache for each OS anyways.

So instead of adding hmc-version to the cache key, please add the name of the operating system.

The cache key had no OS component, so a .minecraft cached on one runner OS
could be restored on another. Restoring an Ubuntu cache (/home/runner/.minecraft)
on macOS lands it where HeadlessMC doesn't look ($HOME is /Users/runner), so the
launch found no installed version: 'Couldn't find object for regex ...'. The
cache is inherently OS-specific (paths, native libraries), so key it by runner.os
to give each OS its own cache. Replaces the hmc-version salt from the previous
commit.
@ChipWolf

Copy link
Copy Markdown
Member Author

You're right, that diagnosis fits the evidence better, cross-OS restore rather than a partial cache. Done in 27e67af: both cache keys now lead with `${{ runner.os }}` (`Linux-26.2-neoforge-hmc` etc.) and I dropped the hmc-version salt. Each OS gets its own cache, which is needed anyway given the OS-specific native libraries, and macOS no longer restores Ubuntu's `/home/runner/.minecraft` into a path it doesn't read. The new keys also miss the old contaminated caches, so this run reinstalls cleanly per-OS.

@okafke

okafke commented Jul 14, 2026

Copy link
Copy Markdown
Member

I reran the workflow twice with the new caching and no caches for macOS and Windows have been created.
I think the problem is that we are caching /home/runner/.minecraft/ regardless of OS. I think the best fix could be to move .minecraft to a path that is similar on every OS, e.g. to $HOME/.minecraft, if $HOME works on all OS. For that we need to also set hmc.mcdir=<.minecraft dir> in the config.properties.

The cache path was hardcoded to /home/runner/.minecraft, which only exists
on Linux. On macOS/Windows HeadlessMC installs .minecraft elsewhere ($HOME
differs, Windows defaults to %APPDATA%), so nothing at /home/runner/.minecraft
got cached and cross-OS restores landed in a directory HeadlessMC never reads.

Pin HeadlessMC's game dir with hmc.mcdir=$HOME/.minecraft in config.properties
(Linux/macOS and Windows) and cache ~/.minecraft, so the cached path and the
install path line up on every runner OS.
@ChipWolf

ChipWolf commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Done in 29fa07e. Set hmc.mcdir=$HOME/.minecraft in both the Linux/macOS and Windows config.properties, and changed the cache path from the hardcoded /home/runner/.minecraft to ~/.minecraft. Now the install dir and the cached dir line up on every runner OS (~ expands to the same $HOME the config uses), so macOS/Windows should actually produce and restore caches instead of caching an empty Linux path. $HOME resolves on all three (bash on Linux/macOS, $HOME in pwsh on Windows → C:\Users\runneradmin), and the download guard already keys off $HOME/.minecraft, so it stays consistent. Kept the per-OS cache key from the last commit since native libraries differ by OS.

@okafke
okafke self-requested a review July 14, 2026 10:43

@okafke okafke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@okafke okafke changed the title fix(mc-versions): correct 26.2 build directory to 26_2 fix(mc-versions): support 26.2 and fix caches on macOS and Windows Jul 14, 2026
@okafke
okafke merged commit 89d0221 into main Jul 14, 2026
35 checks passed
@okafke
okafke deleted the claude/github-issue-137-05c8df branch July 14, 2026 10:44
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.

Support for 26.2

2 participants