tauri-apps/tauri · error
invalid URL pattern for remote URL
Error message
invalid URL pattern for remote URL {url}: {e} What it means
When resolving capabilities, remote URLs declared in a capability's `remote.urls` array are parsed into a `url::Url`. If any entry fails to parse (e.g. it is not a valid absolute URL), the library panics with this message during capability resolution at app startup. Tauri panics because an invalid remote URL makes the capability definition meaningless and there is no safe fallback.
Solutions
- Fix the `remote.urls` entry in the offending capability file (under src-tauri/capabilities/) to be a full absolute URL including scheme, e.g. `https://example.com`.
- Validate each URL by parsing it (e.g. `new URL(s)` / `url::Url::parse(s)`) before committing the capability file.
- If the URL is intentionally wildcarded, remember `Url::parse` requires a scheme — use `https://*.example.com` style patterns, not bare domains.
Example fix
// before (src-tauri/capabilities/main.json)
"remote": { "urls": ["localhost:1420"] }
// after
"remote": { "urls": ["http://localhost:1420"] } Defensive patterns
Strategy: validation
Validate before calling
function isValidRemoteUrl(u) { try { const url = new URL(u); return url.protocol === 'http:' || url.protocol === 'https:'; } catch { return false; } }
// check every remote.urls entry in src-tauri/capabilities/*.json before building Type guard
const isCapabilityRemote = (c) => typeof c === 'object' && c !== null && Array.isArray(c.remote?.urls) && c.remote.urls.every(isValidRemoteUrl);
Prevention
- Always include the scheme (http:// or https://) in remote.urls entries
- Validate capability files in CI by parsing each remote URL with `new URL()` or `url::Url::parse`
- Prefer the tauri CLI/schema validation over hand-editing capability JSON/TOML
When it happens
Trigger: A capability TOML/JSON file contains `remote.urls = ["..."]` with a string that `url::Url::parse` rejects — missing scheme ("localhost:5173" instead of "http://localhost:5173"), typo'd scheme ("http:/"), or stray characters/whitespace.
Common situations: Hand-editing capability files and omitting the `http://` scheme; copying a host:port pair from a dev-server output; typos introduced while migrating config from tauri.conf.json to capability files.
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
- beforeDevCommand ` ` failed with exit code
- Can't extract file name from path
- Can't read source directory
- cannot use both `resources` and `resources_map`
- Could not find a capability to update
AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18).
Data as JSON: /api/errors/76a6c9d5d449e8f1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tauri-utils/src/acl/resolved.rs:269
}
fn resolve_command(
commands: &mut BTreeMap<String, Vec<ResolvedCommand>>,
command: String,
capability: &Capability,
scope_id: Option<ScopeKey>,
#[cfg(debug_assertions)] referenced_by_permission_identifier: &str,
) -> Result<(), Error> {
let mut contexts = Vec::new();
if capability.local {
contexts.push(ExecutionContext::Local);
}
if let Some(remote) = &capability.remote {
contexts.extend(remote.urls.iter().map(|url| {
ExecutionContext::Remote {
url: url
.parse()
.unwrap_or_else(|e| panic!("invalid URL pattern for remote URL {url}: {e}")),
}
}));
}
for context in contexts {
let resolved_list = commands.entry(command.clone()).or_default();
resolved_list.push(ResolvedCommand {
context,
#[cfg(debug_assertions)]
referenced_by: ResolvedCommandReference {
capability: capability.identifier.clone(),
permission: referenced_by_permission_identifier.to_owned(),
},
windows: parse_glob_patterns(capability.windows.clone())?,
webviews: parse_glob_patterns(capability.webviews.clone())?,
scope_id,
});View on GitHub (pinned to 460ec35447)