responsively-org/responsively-app · warning · Error

Invalid URL

Error message

Invalid URL

What it means

handleDrop accepts dragged text and tries to construct a URL from it. If the text parses but its protocol is neither http: nor https: (or it fails to parse at all, which throws from the URL constructor and lands in the same catch), the code throws 'Invalid URL' which is immediately caught and logged to console.error. It is a control-flow signal to reject non-web URLs dropped onto the address bar.

Source

Thrown at desktop-app/src/renderer/components/ToolBar/AddressBar/index.tsx:141

    e.preventDefault();
    setIsDragOver(true);
  };

  const handleDragExit = (e: DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
  };

  const handleDrop = (e: DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
    const draggedText = e.dataTransfer.getData('text/plain');
    try {
      const draggedUrl = new URL(draggedText);
      if (draggedUrl.protocol === 'http:' || draggedUrl.protocol === 'https:') {
        dispatchAddress(draggedUrl.href);
      } else {
        throw new Error('Invalid URL');
      }
    } catch (err) {
      // eslint-disable-next-line no-console
      console.error('Invalid URL', err);
    }
  };

  const deleteCookies = async () => {
    setDeleteCookiesLoading(true);
    await webViewPubSub.publish(ADDRESS_BAR_EVENTS.DELETE_COOKIES);
    setDeleteCookiesLoading(false);
  };

  const deleteStorage = async () => {
    setDeleteStorageLoading(true);
    await webViewPubSub.publish(ADDRESS_BAR_EVENTS.DELETE_STORAGE);
    setDeleteStorageLoading(false);
  };

View on GitHub (pinned to e5623c5a70)

Solutions

  1. Validate the text with a regex or URL parse before constructing, and silently ignore non-URL drops
  2. Show a user-visible toast/notification instead of only logging to console so the user knows the drop was rejected
  3. Allow useful schemes (file:, about:) explicitly if product requirements permit
  4. Prefix bare text like 'example.com' with https:// before parsing

Example fix

// before
const draggedText = e.dataTransfer.getData('text/plain');
const draggedUrl = new URL(draggedText);
// after
const draggedText = e.dataTransfer.getData('text/plain').trim();
if (!/^https?:\/\//i.test(draggedText)) return;
const draggedUrl = new URL(draggedText);
Defensive patterns

Strategy: validation

Validate before calling

const text = e.dataTransfer.getData('text/plain').trim();
let isValidDropUrl = false;
try {
  const u = new URL(text);
  isValidDropUrl = u.protocol === 'http:' || u.protocol === 'https:';
} catch { isValidDropUrl = false; }

Type guard

function isHttpUrl(s: string): boolean {
  try {
    const u = new URL(s);
    return u.protocol === 'http:' || u.protocol === 'https:';
  } catch {
    return false;
  }
}

Try / catch

try {
  const draggedUrl = new URL(draggedText);
  if (draggedUrl.protocol === 'http:' || draggedUrl.protocol === 'https:') {
    dispatchAddress(draggedUrl.href);
  }
} catch (err) {
  console.warn('Ignoring non-URL drop:', draggedText, err);
  // optionally notifyUser('Not a valid web link')
}

Prevention

When it happens

Trigger: Dragging text, a javascript: or file: link, or any non-URL string onto the address bar; new URL(draggedText) throws SyntaxError or the protocol check fails and the explicit throw fires.

Common situations: Users dragging bookmarks with custom schemes, dragging plain text from an editor, dragging file:// links from the OS file manager, or dragging mailto:/ftp: links from a browser.

Related errors


AI-assisted analysis of responsively-org/responsively-app@e5623c5a70 (2026-08-31). Data as JSON: /api/errors/d7d489ad553e8227. Report an issue: GitHub.