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
- Validate the text with a regex or URL parse before constructing, and silently ignore non-URL drops
- Show a user-visible toast/notification instead of only logging to console so the user knows the drop was rejected
- Allow useful schemes (file:, about:) explicitly if product requirements permit
- 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
- Validate with /^https?:\/\//i before constructing a URL
- Never rely on exceptions for expected user input; return early instead of throw
- Surface rejected drops with UI feedback, not just console.error
- Consider auto-prepending https:// for bare domains
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.