tw93/Pake · info

Cannot open special URL with shell:

Error message

Cannot open special URL with shell:

What it means

handleExternalLink opens non-internal URLs in the system browser via the Tauri shell plugin (`invoke("plugin:shell|open")`). Before doing so it checks isSpecialDownload(url), which matches blob:, data:, and similar special-scheme URLs. If the URL is special, the function deliberately refuses to hand it to the OS shell and logs this warning instead — blob/data URLs cannot be opened by the OS and attempting to would fail or misbehave.

Solutions

  1. This is expected behavior for blob:/data: URLs — the page's own download handling (anchor `download` attribute) should process them; ensure the click is not being intercepted before the browser's native download logic runs.
  2. If the blob should be saved as a file, create an anchor element with the blob URL and a `download` attribute and click it programmatically, rather than routing it to the shell plugin.
  3. If a legitimate http(s) link is being misclassified, inspect isSpecialDownload's matching and the URL construction — an empty-string or null href coerced into a special-looking URL can trigger the guard.
  4. For apps that must export files externally, offer the http(s) CDN URL of the asset instead of a blob URL so the shell open path works.

Example fix

// before
const handleExternalLink = (url) => {
  if (isSpecialDownload(url)) {
    console.warn("Cannot open special URL with shell:", url);
    return;
  }
  invoke("plugin:shell|open", { path: url });
// after (route blob URLs to a native browser download instead of refusing silently)
const handleExternalLink = (url, anchorElement) => {
  if (isSpecialDownload(url)) {
    if (anchorElement?.download) return; // let the anchor's download attribute handle it
    const a = document.createElement("a");
    a.href = url;
    a.download = "";
    a.click();
    return;
  }
  invoke("plugin:shell|open", { path: url });
Defensive patterns

Strategy: fallback

Validate before calling

function isOpenableWithShell(url) {
  try {
    const scheme = new URL(url, location.href).protocol;
    return scheme === "http:" || scheme === "https:";
  } catch {
    return false;
  }
}

Type guard

const isHttpUrl = (url) => {
  try { return /^https?:$/.test(new URL(url, location.href).protocol); }
  catch { return false; }
};

Try / catch

invoke("plugin:shell|open", { path: url }).catch((error) => {
  console.warn("Shell open failed, falling back to anchor:", error);
  const a = document.createElement("a");
  a.href = url;
  a.target = "_blank";
  a.rel = "noopener";
  a.click();
});

Prevention

When it happens

Trigger: A user clicks (or the page triggers) an external link whose href is a `blob:` URL (common for client-generated downloads, PDF previews, or media streams) or a `data:` URL (inline CSV/Base64 downloads). The special-scheme check short-circuits and prints "Cannot open special URL with shell:" before any shell invoke happens.

Common situations: Clicking an 'Export as PDF/CSV' button on a web app that generates the file client-side as a blob; opening a preview of an uploaded document served as a blob URL; sites that build `data:text/csv,...` download links; canvas/image 'download' buttons that create object URLs at click time.

Related errors


AI-assisted analysis of tw93/Pake@c8fe8a3f1a (2026-09-20). Data as JSON: /api/errors/288c03655cea70ec. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/inject/event.js:716

    document.body.appendChild(anchor);
    anchor.click();
    document.body.removeChild(anchor);
  }

  // process special download protocol['data:','blob:']
  const isSpecialDownload = (url) =>
    ["blob", "data"].some((protocol) => url.startsWith(protocol));

  // Cmd/Ctrl+click is a browser "open related" gesture, not "save as".
  // Only the download attribute and downloadable-file heuristics force a
  // download; modifiers must not rewrite ordinary navigation.
  const isDownloadRequired = (url, anchorElement, _e) =>
    Boolean(anchorElement.download) || isDownloadableFile(url);

  const handleExternalLink = (url) => {
    // Don't try to open blob: or data: URLs with shell
    if (isSpecialDownload(url)) {
      console.warn("Cannot open special URL with shell:", url);
      return;
    }

    invoke("plugin:shell|open", {
      path: url,
    }).catch((error) => {
      console.error("Failed to open URL with shell:", url, error);
    });
  };

  const isInternalUrl = (url) => matchesInternalUrl(url, window.location.href);

  const detectAnchorElementClick = (e) => {
    // Safety check: ensure e.target exists and is an Element with closest method
    if (!e.target || typeof e.target.closest !== "function") {
      return;
    }
    const anchorElement = e.target.closest("a");

View on GitHub (pinned to c8fe8a3f1a)