{"record":{"id":"eeb253758ed3b611","repo":"jdx/mise","slug":"expected-exactly-one-hex-otp-build-record-for-rel","errorCode":null,"errorMessage":"expected exactly one Hex OTP build record for {release_tag}, found {}","messagePattern":"expected exactly one Hex OTP build record for (.+?), found (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/plugins/core/erlang.rs","lineNumber":805,"sourceCode":"        lock_platforms\n            .get(platform_key)\n            .is_some_and(|pi| pi.install.as_deref() == Some(\"source\"))\n    } else {\n        erlang_compile == Some(true)\n    }\n}\n\nfn parse_hex_build_checksum(builds: &str, release_tag: &str) -> Result<String> {\n    let matching = builds\n        .lines()\n        .filter_map(|line| {\n            let parts = line.split_whitespace().collect::<Vec<_>>();\n            (parts.first() == Some(&release_tag)).then_some(parts)\n        })\n        .collect::<Vec<_>>();\n\n    if matching.len() != 1 {\n        bail!(\n            \"expected exactly one Hex OTP build record for {release_tag}, found {}\",\n            matching.len()\n        );\n    }\n\n    let checksum = matching[0]\n        .get(3)\n        .ok_or_else(|| eyre::eyre!(\"Hex OTP build record for {release_tag} has no checksum\"))?;\n    if !regex!(r\"^[0-9a-f]{64}$\").is_match(checksum) {\n        bail!(\"invalid Hex OTP checksum for {release_tag}: {checksum}\");\n    }\n\n    Ok(format!(\"sha256:{checksum}\"))\n}\n\n#[cfg(any(linux, test))]\nfn require_locked_precompiled_checksum(version: &str, checksum: Option<&str>) -> Result<String> {\n    let checksum = checksum.ok_or_else(|| {","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/plugins/core/erlang.rs#L787-L823","documentation":"For Linux precompiled OTP, mise downloads builds.txt from builds.hex.pm for the arch/OS and expects exactly one line whose first whitespace-separated field is the release tag OTP-<version>. Zero matches means Bob has not published that version for your arch/OS (too new, too old, or skipped); multiple matches means duplicate records upstream. Fatal when erlang.compile=false; otherwise it becomes a fallback reason and OTP compiles from source.","triggerScenarios":"`mise install erlang@<v>` with compile=false where <v> is a freshly released OTP patch not yet built by Bob for your os_ver (arm64 typically lags amd64), an old version whose builds were dropped, or a version typo; also `mise lock` with compile=false on the same conditions.","commonSituations":"Pinning a brand-new OTP within hours of release on an arm64/Ubuntu-24.04 runner; version strings copied from erlang.org announcements before Bob catches up; duplicated upstream records after hex.pm incidents.","solutions":["Pick a version that exists for your platform: check https://builds.hex.pm/builds/otp/amd64/ubuntu-24.04/builds.txt (substitute your arch/OS) and pin that","If the version just released, wait a day or two for Bob builds, or temporarily `mise settings set erlang.compile true`","Verify the version string with `mise ls-remote erlang` — typos produce the same 'found 0' result","If the file genuinely shows duplicates, report to the hex-core Bob project and use compile=true meanwhile"],"exampleFix":"# before\n$ mise use -p erlang@27.3   # not yet in builds.txt → found 0\n\n# after — pick a published build (or compile)\n$ mise use -p erlang@27.2\n# or: mise settings set erlang.compile true && mise install erlang@27.3","handlingStrategy":"validation","validationCode":"# confirm Bob published this OTP for your arch/OS before a compile=false install\nVER=27.1; ARCH=amd64; OS=ubuntu-24.04\ncurl -fsSL \"https://builds.hex.pm/builds/otp/$ARCH/$OS/builds.txt\" | grep -q \"^OTP-$VER \" \\\n  && mise install erlang@$VER \\\n  || { echo \"no Bob build for OTP-$VER on $ARCH/$OS — choosing compile or another version\"; exit 1; }","typeGuard":null,"tryCatchPattern":"if ! mise install erlang@27.1; then\n  # precompiled record missing — either wait for Bob, or build from source\n  mise settings set erlang.compile true && mise install erlang@27.1\nfi","preventionTips":["Pin OTP patch versions that already appear in builds.txt instead of tracking the newest release","arm64 builds usually lag amd64 — allow extra settle time before pinning fresh versions on arm64"],"tags":["mise","erlang","hex-pm","bob","builds-txt","version-not-found","precompiled"],"backgroundTag":"release-asset-not-found","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}