jdx/mise · error · eyre::Report

S3 URL must include bucket name

Error message

S3 URL must include bucket name

What it means

S3Url::parse requires a non-empty host component as the bucket name. This error fires when the `s3://` URL has no host at all (host_str() is None) or an empty one — i.e. the bucket was omitted.

Source

Thrown at src/backend/s3.rs:86

    key: String,
}

impl S3Url {
    /// Parse an S3 URL like "s3://bucket/path/to/object?region=us-west-2"
    fn parse(url_str: &str) -> Result<Self> {
        let url = Url::parse(url_str).map_err(|e| eyre!("Invalid S3 URL: {e}"))?;

        if url.scheme() != "s3" {
            bail!("URL must use s3:// scheme, got: {}", url.scheme());
        }

        let bucket = url
            .host_str()
            .ok_or_else(|| eyre!("S3 URL must include bucket name"))?
            .to_string();

        if bucket.is_empty() {
            bail!("S3 URL must include bucket name");
        }

        let key = url.path().trim_start_matches('/').to_string();

        Ok(Self { bucket, key })
    }
}

/// S3 backend for downloading tools from Amazon S3 or S3-compatible storage
#[derive(Debug)]
pub(crate) struct S3Backend {
    ba: Arc<BackendArg>,
    /// Cached S3 client, lazily initialized
    client: OnceCell<S3Client>,
}

#[derive(Debug, Clone, Copy)]
struct S3Options<'a> {

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Add the bucket: `s3://my-bucket/path/to/asset.tar.gz`
  2. Check template variables (e.g. `s3://{{bucket}}/key`) actually render a non-empty value
  3. Use exactly two slashes after s3: when the bucket follows directly

Example fix

# before
url = "s3:///releases/tool-1.0.0.tar.gz"

# after
url = "s3://my-bucket/releases/tool-1.0.0.tar.gz"
Defensive patterns

Strategy: validation

Validate before calling

case "$url" in s3://?*/) echo ok;; *) echo "bad s3 url: $url";; esac

Type guard

fn has_s3_bucket(s: &str) -> bool {
    url::Url::parse(s).map(|u| u.host_str().is_some_and(|h| !h.is_empty())).unwrap_or(false)
}

Prevention

When it happens

Trigger: Writing `url = "s3:///path/to/asset.tar.gz"` (three slashes) or a URL where the bucket position is empty. It is the immediate follow-on check after the s3 scheme check passes.

Common situations: Editing an s3:// URL and deleting the bucket, template-rendering the URL with an empty bucket variable, or copy-paste that loses the bucket segment.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/1f93caf983d84978. Report an issue: GitHub.