denoland/deno · error
Can't convert url ("{}") to filename.
Error message
Can't convert url ("{}") to filename. What it means
The local (LRU) cache directory computes a storage path from a URL the same way the HTTP cache does: it calls base_url_to_filename_parts (libs/cache_dir/common.rs:13), which only accepts http, https, data and blob schemes. When the scheme is anything else the helper returns None and this InvalidInput io::Error is produced with the offending URL. It guards the on-disk layout of the DENO_DIR local cache from URLs it cannot name deterministically.
Source
Thrown at libs/cache_dir/local.rs:688
} else {
// if any non-ending path part has a known extension, hash it in order to
// prevent collisions where a filename has the same name as a directory name
has_known_extension(part)
};
// the hash symbol at the start designates a hash for the url part
hash_context_specific
|| part.starts_with('#')
|| has_forbidden_chars(part)
|| last_ext.is_none() && FORBIDDEN_WINDOWS_NAMES.contains(part)
|| part.ends_with('.')
}
// get the base url
let port_separator = "_"; // make this shorter with just an underscore
let Some(mut base_parts) = base_url_to_filename_parts(url, port_separator)
else {
return Err(std::io::Error::new(
ErrorKind::InvalidInput,
format!("Can't convert url (\"{}\") to filename.", url),
));
};
if base_parts[0] == "https" {
base_parts.remove(0);
} else {
let scheme = base_parts.remove(0);
base_parts[0] = Cow::Owned(format!("{}_{}", scheme, base_parts[0]));
}
// first, try to get the filename of the path
let path_segments = url_path_segments(url);
let mut parts = base_parts
.into_iter()
.chain(path_segments.map(Cow::Borrowed))
.collect::<Vec<_>>();View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Look at the URL in the message and change the caller to pass an http/https/data/blob URL, which are the only schemes the cache naming supports.
- If the resource is genuinely local (file:), bypass this cache API and address it by its real filesystem path instead of a URL.
- For custom schemes, hash or encode the URL into your own file name instead of routing it through base_url_to_filename_parts.
Example fix
// before
let file_path = local_lru_cache.get(&Url::parse("asset://logo.png")?)?; // Err: Can't convert url ("asset://logo.png") to filename.
// after
let url = Url::parse("asset://logo.png")?;
if !matches!(url.scheme(), "http" | "https" | "data" | "blob") {
// handle non-cacheable schemes yourself (e.g. hash the whole URL)
return Ok(None);
}
let file_path = local_lru_cache.get(&url)?; Defensive patterns
Strategy: validation
Validate before calling
fn can_local_cache_name(url: &url::Url) -> bool {
matches!(url.scheme(), "http" | "https" | "data" | "blob")
}
if !can_local_cache_name(&url) {
return Ok(None); // skip the local cache for unsupported schemes
} Try / catch
match local_cache.get(&url) {
Ok(Some(data)) => { /* hit */ }
Ok(None) => { /* miss */ }
Err(err) if err.kind() == std::io::ErrorKind::InvalidInput => {
// unsupported scheme — fall back to a scheme-appropriate path
}
Err(err) => return Err(err),
} Prevention
- Route truly local resources by path, not URL, so the URL-keyed caches never see file:/custom schemes.
- Add unit tests covering every scheme your loader can produce so a new scheme fails in CI, not in production.
When it happens
Trigger: Using the LocalLruCache (DENO_DIR/local fast cache) API that derives file names from URLs with a non-http/https/data/blob scheme, e.g. caching a "file://…" or custom-protocol resource that the local cache key logic tries to convert via base_url_to_filename_parts.
Common situations: Switching a cache from only-remote to mixed local resources; a module loader or extension feeding vendor/custom scheme URLs into the local cache; refactors that changed which URLs reach the local cache; tests with synthetic schemes.
Related errors
- Can't convert url ("{}") to filename.
- ERR_INVALID_URL_SCHEME
- ERR_INVALID_URL
- ERR_HTTP2_PAYLOAD_FORBIDDEN
- ERR_INVALID_URL_SCHEME
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/a01188c200365d90.
Report an issue: GitHub.