Uh oh!
There was an error while loading. Please reload this page.
fix(publish): pass multipart JSON via files, not inline -F values - #13
Merged
Conversation
curl's -F parses ; and , inside inline values as attribute separators. Any changelog containing them - every HTML entity does - truncated the JSON part, so CurseForge rejected metadata as invalid JSON and Hangar failed to read the request. The <file form reads content out-of-band and is immune to the payload's characters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RJmrCPRxnwMnWQvGKpEpGY
tastybento added a commit
to BentoBoxWorld/BentoBox
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Level
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/ChunkBlock
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Border
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/InvSwitcher
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/AcidIsland
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Challenges
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Parkour
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/ControlPanel
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/MagicCobblestoneGenerator
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/GushBlock
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Warps
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Biomes
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Boxed
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/BSkyBlock
that referenced
this pull request
Jul 29, 2026
The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
tastybento added a commit
to BentoBoxWorld/Biomes
that referenced
this pull request
Jul 30, 2026
## What
Bumps the pinned SHA of the shared `publish-platforms.yml` reusable
workflow to `1f91a0e` (master HEAD of `BentoBoxWorld/.github`).
## Why
The pinned version passes the CurseForge `metadata` and Hangar
`versionUpload` multipart JSON as an inline curl value:
```
-F "metadata=${META};type=application/json"
```
curl reads a `;` inside an inline `-F` value as the start of a
`type=`/`filename=` attribute, so the JSON is silently truncated at the
first semicolon in the release body. Both platforms then reject the
upload:
- CurseForge — `{"errorCode":1002,"errorMessage":"Error in field
\`metadata\`: Invalid JSON."}`
- Hangar — `{"status":400,"detail":"Failed to read request"}`
This is latent, not theoretical: it took down the AOneBlock 1.26.3
publish
([run](https://github.com/BentoBoxWorld/AOneBlock/actions/runs/30468254213))
because those release notes happened to contain one semicolon. Any
release body with a semicolon in it trips this.
BentoBoxWorld/.github#13 fixed it on 2026-07-20 by writing the JSON to a
file and using curl's `<file` form (`-F
"metadata=<cf_meta.json;type=application/json"`). This repo was still
pinned to the commit before that fix.
Modrinth publishing is unaffected — it does not go through this
workflow.
No behaviour change beyond the fix; the pin is the only line touched.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
curl's
-Fparses;and,inside inline values as attribute separators. Any changelog containing them — every HTML entity does — truncated the JSON part of the multipart upload, so CurseForge rejectedmetadataas invalid JSON (error 1002) and Hangar failed to read the request (HTTP 400). Seen on the AcidIsland 2.0.0 release: https://github.com/BentoBoxWorld/AcidIsland/actions/runs/29710523349The
<fileform reads the part content out-of-band, so the payload can contain any characters. Validated by re-running the AcidIsland 2.0.0 publish pinned to this branch's SHA.🤖 Generated with Claude Code
https://claude.ai/code/session_01RJmrCPRxnwMnWQvGKpEpGY