Skip to content

perry-stdlib: web-fetch without crypto fails to build (turnloop_client uses base64, which turnloop-http-client does not enable) #11149

Closed

Description

@steinybot

Summary

perry-stdlib fails to build with web-fetch enabled and crypto off. turnloop_client::decode_basic uses the base64 crate, but turnloop-http-client (which web-fetch enables) does not turn on the optional dep:base64. The workspace build passes only because crypto and the TLS features enable base64 too.

Auto-optimize builds the stdlib with only the features a program uses, so any program that calls fetch and does not use crypto fails to compile its stdlib. It then falls back to the prebuilt libraries and fails to link against them.

Repro

On main at d8f24f15edc4:

cargo build -p perry-stdlib --no-default-features --features web-fetch
error[E0432]: unresolved import `base64`
   --> crates/perry-stdlib/src/turnloop_client/mod.rs:757:9
error[E0433]: cannot find module or crate `base64` in this scope
   --> crates/perry-stdlib/src/turnloop_client/mod.rs:758:15

--features web-fetch,crypto builds.

/// Split a `Basic` credential back into user and password.
fn decode_basic(encoded: &str) -> Option<(String, String)> {
use base64::Engine;
let raw = base64::engine::general_purpose::STANDARD
.decode(encoded.trim())
.ok()?;
let text = String::from_utf8(raw).ok()?;
let (user, pass) = text.split_once(':')?;
Some((user.to_string(), pass.to_string()))

Fix

Add dep:base64 to turnloop-http-client:

turnloop-http-client = ["dep:turnloop-http", "dep:turnloop-tls", "dep:perry-tls-session", "dep:url", "dep:http"]

turnloop-http-client = ["dep:turnloop-http", "dep:turnloop-tls", "dep:perry-tls-session", "dep:url", "dep:http", "dep:base64"]

With that change the repro command above builds.

Why CI did not catch it

CI builds perry-stdlib with the full feature set, where crypto supplies base64. The failure shows up only in a per-feature build, which is the build auto-optimize does for user programs. #7764 and #9719 were the same class of break. A CI job that builds the stdlib once per user-facing feature (or with cargo hack --each-feature) would catch the next one.

Introduced

#10354 (turnloop replaces tokio), first released in 0.5.1640. 0.5.1638 builds.

Environment

macOS 26.6.2 arm64. Found compiling a program that uses fetch and no crypto.

Activity

  1. proggeramlug commented on Sep 23, 2026

    @proggeramlug
    Contributor

    THanks @steinybot for your immediate and thorough tests. :)

    I'm on it, as you can tell there are many changes coming through right now so this should be resolved shortly!

  2. proggeramlug commented on Sep 23, 2026

    @proggeramlug
    Contributor

    PR #11116 (turnloop-http-client gains dep:base64) is the fix for this, and it's MERGEABLE. It makes the same one-line change you proposed. On the effect: #11116's description says auto-optimize falls back to the prebuilt full-feature archive and exits 0, but you saw that fallback fail to link. We'll note that on the PR so the fallback path is checked as well.

  3. proggeramlug commented on Sep 25, 2026

    @proggeramlug
    Contributor

    Fixed by #11116 (merged): turnloop-http-client now enables dep:base64.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions