Skip to content

solx 0.5.1: fix the broken .pyz installer (shebang swap corrupts the zipapp)#31

Merged
Shu-Wan merged 2 commits into
mainfrom
fix-pyz-install
Jun 11, 2026
Merged

solx 0.5.1: fix the broken .pyz installer (shebang swap corrupts the zipapp)#31
Shu-Wan merged 2 commits into
mainfrom
fix-pyz-install

Conversation

@Shu-Wan

@Shu-Wan Shu-Wan commented Jun 11, 2026

Copy link
Copy Markdown
Owner

solx 0.5.1 — fix the broken .pyz installer

v0.5.0's install.sh produced a solx that can't start. It rebound the
zipapp's interpreter by swapping the shebang bytes in place, but a zipapp
records its central-directory offsets as absolute file positions that include
the shebang line
. Replacing the shebang with a different-length interpreter
path shifts every offset, so zipimport (which executes the archive) rejects
it:

SyntaxError: source code cannot contain null bytes

The build stamps the CI runner's long interpreter path
(#!/home/runner/work/_temp/uv-python-dir/…/python3.11), so no local
interpreter path matches its length — essentially every .pyz install was
broken.
zipfile tolerates the corrupted archive on read, which is why the
build's own check never caught it; only zipimport is strict.

Fix

install.sh now:

  • Extracts the payload and rebuilds the archive around the local
    interpreter (python -m zipfile -epython -m zipapp), which regenerates
    the offsets — instead of byte-swapping the shebang.
  • Smoke-tests the result (solx --version) before reporting success, so a
    broken install can never be reported as success again.
  • Falls back to a uv-managed interpreter if the resolved one can't run a
    zipapp.

Verification

  • New install.sh run end-to-end against the live v0.5.0 release → installed
    solx runs (0.5.0).
  • sh -n clean; full suite green (247 passed).

Version

Bumps to 0.5.1 across __init__.py, pyproject.toml, SKILL.md, and
uv.lock; changelog adds [0.5.1] and relabels the released [Unreleased]
block as [0.5.0] — 2026-06-10.

🤖 Generated with Claude Code

Shu-Wan and others added 2 commits June 10, 2026 18:18
…bang

install.sh rebound the interpreter by replacing the shebang bytes in
place, but a zipapp records central-directory offsets as absolute file
positions that include the shebang line. A different-length interpreter
path shifted every offset, so zipimport rejected the archive ("bad
central directory size or offset") and solx died on startup with
"SyntaxError: source code cannot contain null bytes". The build stamps
the CI runner's long interpreter path, so no local path matched its
length and essentially every .pyz install was broken; zipfile tolerated
the corruption on read, so the build's own check never caught it.

install.sh now extracts the payload and rebuilds the archive around the
local interpreter (regenerating the offsets), then smoke-tests the
result before reporting success, falling back to a uv-managed
interpreter when the resolved one can't run a zipapp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build job only uploaded solx.pyz; nothing executed it, and the
release smoke check that did exist relied on zipfile, which tolerates the
offset corruption a shebang swap produces. Add a step that runs the
artifact in place and end-to-end through install.sh, binding it to an
interpreter whose path length differs from the build shebang (a symlink
under $RUNNER_TEMP) — the exact condition under which an in-place shebang
swap corrupts the archive. A regression now fails the build.

To let the smoke test pin that interpreter, install.sh's SOLX_PYTHON now
accepts an explicit interpreter path (anything with a slash) in addition
to a version, used as-is with no uv required — which also gives a no-uv
machine a working install path. The managed-interpreter fallback derives
its version from the chosen interpreter and errors clearly when uv is
absent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Shu-Wan Shu-Wan merged commit 1f967cf into main Jun 11, 2026
6 checks passed
@Shu-Wan Shu-Wan deleted the fix-pyz-install branch June 11, 2026 01:32
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