denoland/deno · error

Can't convert url ("{}") to filename.

Error message

Can't convert url ("{}") to filename.

What it means

url_to_filename() maps a Url to a cache filename by first splitting it into [scheme, host] parts via base_url_to_filename_parts (libs/cache_dir/common.rs:13). That helper only understands the http, https, data and blob schemes; every other scheme logs "Don't know how to create cache name for scheme" and returns None, which url_to_filename converts into this InvalidInput io::Error echoing the offending URL. It exists because arbitrary schemes (file:, npm:, custom protocols) cannot be mapped deterministically into the cache layout this library maintains.

Source

Thrown at libs/cache_dir/cache.rs:99

        actual,
      }))
    } else {
      Ok(())
    }
  }
}

/// Turn provided `url` into a hashed filename.
/// URLs can contain a lot of characters that cannot be used
/// in filenames (like "?", "#", ":"), so in order to cache
/// them properly they are deterministically hashed into ASCII
/// strings.
pub fn url_to_filename(url: &Url) -> std::io::Result<PathBuf> {
  // Replaces port part with a special string token (because
  // ":" cannot be used in filename on some platforms).
  // Ex: $DENO_DIR/remote/https/deno.land/
  let Some(cache_parts) = base_url_to_filename_parts(url, "_PORT") else {
    return Err(std::io::Error::new(
      ErrorKind::InvalidInput,
      format!("Can't convert url (\"{}\") to filename.", url),
    ));
  };

  let rest_str = if let Some(query) = url.query() {
    let mut rest_str =
      String::with_capacity(url.path().len() + 1 + query.len());
    rest_str.push_str(url.path());
    rest_str.push('?');
    rest_str.push_str(query);
    Cow::Owned(rest_str)
  } else {
    Cow::Borrowed(url.path())
  };

  // NOTE: fragment is omitted on purpose - it's not taken into
  // account when caching - it denotes parts of webpage, which

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Inspect the URL printed in the message and fix the caller to pass an http/https (or data/blob) URL — this is almost always a caller bug, not a cache bug.
  2. If you must handle other schemes, branch on url.scheme() before calling url_to_filename and build your own filename for the unsupported schemes instead of relying on the cache layout.
  3. Check where the URL originates (module loader, CLI arg, config file) and make sure a file path or bare specifier was not coerced into a Url with an unexpected scheme.

Example fix

// before
let path = url_to_filename(&Url::parse("file:///mod.ts")?)?; // Err: Can't convert url ("file:///mod.ts") to filename.

// after
let url = Url::parse("file:///mod.ts")?;
let path = match url.scheme() {
  "http" | "https" | "data" | "blob" => url_to_filename(&url)?,
  other => {
    return Err(std::io::Error::new(
      std::io::ErrorKind::InvalidInput,
      format!("unsupported cache scheme: {other}"),
    ))
  }
};
Defensive patterns

Strategy: validation

Validate before calling

fn is_cacheable_url(url: &url::Url) -> bool {
  matches!(url.scheme(), "http" | "https" | "data" | "blob")
}

// before caching:
if !is_cacheable_url(&url) {
  return Err(std::io::Error::new(
    std::io::ErrorKind::InvalidInput,
    format!("cannot cache non-remote url: {url}"),
  ));
}
let path = url_to_filename(&url)?;

Try / catch

match url_to_filename(&url) {
  Ok(path) => { /* use path */ }
  Err(err) if err.kind() == std::io::ErrorKind::InvalidInput => {
    // unsupported scheme (not http/https/data/blob) — handle locally or skip caching
  }
  Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling url_to_filename() directly, or indirectly through HttpCache operations (get/put/remove with cache keys built from URLs), with a URL whose scheme is not http/https/data/blob — e.g. Url::parse("file:///mod.ts"), "npm:pkg", "node:fs", or a custom protocol URL.

Common situations: Custom module loaders that produce non-HTTP specifiers and feed them into the HTTP cache; passing a file path or package specifier where a remote URL is required; newer code paths routing URLs of previously-unseen schemes into the cache; tests using example/spec URLs like "example:foo".

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/fd4daa57a53ed9a6. Report an issue: GitHub.