denoland/deno · error · std::io::Error
InvalidInput
InvalidInput
Error message
Can't convert url ("{}") to filename. What it means
libs/cache_dir's url_to_filename converts a remote-module URL into a cache file path by deriving parts from the URL's origin via base_url_to_filename_parts. URLs whose scheme/shape cannot be represented as cache paths (unsupported scheme, no host, etc.) yield None and this InvalidInput error, since the URL cannot map to a filesystem location.
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) 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, whichView on GitHub (pinned to 336da420f4)
Solutions
- Only pass remote http/https URLs to cache-path APIs; handle file:/blob: URLs with local-path logic instead.
- Validate the URL scheme and host before requesting a cache filename.
- Fix malformed/dynamically built URLs (missing host, wrong scheme).
- Catch std::io::Error with ErrorKind::InvalidInput and fall back to a non-cache path.
Example fix
// before
let path = get_cache_filename(&Url::parse("file:///local/mod.ts")?).unwrap();
// after
let url = Url::parse("https://deno.land/x/mod.ts")?;
if url.scheme().starts_with("http") {
let path = get_cache_filename(&url)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
function isCacheable(u: URL): boolean {
return (u.protocol === "https:" || u.protocol === "http:") && u.hostname !== "";
} Type guard
function isRemoteHttpUrl(u: URL): u is URL {
return /^https?:$/.test(u.protocol) && u.hostname.length > 0;
} Try / catch
try {
const path = get_cache_filename(url);
} catch (e) {
if (e instanceof Deno.errors.InvalidData || e.code === "InvalidInput") {
// non-cacheable URL: skip caching or handle via local loader
} else throw e;
} Prevention
- Route file:/blob:/data: URLs to local-module handling, never the remote cache.
- Validate scheme and host before cache-path conversion.
- Fix URL construction bugs (missing host, typo'd schemes) at the source.
When it happens
Trigger: Calling local_path_for_url/get_cache_filename with a URL that has no base-encodable parts — e.g. non-http(s)/data-unsupported schemes (file:, blob:, custom schemes), URLs without a host, or malformed URLs accepted by the Url parser but not cacheable.
Common situations: Caching code fed blob: or file: URLs; tests passing synthetic URLs; custom loaders emitting non-remote URLs into the HTTP cache path; typos like htp:// in dynamically constructed URLs.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- InvalidInput
- Can't convert url ("{}") to filename.
- Can't convert url ("{}") to filename.
- failed to open cache db at {}
- Unable to construct URL from the path of cwd: {}
AI-assisted analysis of denoland/deno@336da420f4 (2026-09-11).
Data as JSON: /api/errors/7178eff668b1f411.
Report an issue: GitHub.