{"record":{"id":"19e36e12485926bc","repo":"kovidgoyal/kitty","slug":"invalid-url","errorCode":null,"errorMessage":"Invalid URL","messagePattern":"Invalid URL","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"kitty/options/utils.py","lineNumber":161,"sourceCode":"        return func, parts\n    return 'kitten', parts[1:]\n\n\n@func_with_args('open_url')\ndef open_url_parse(func: str, rest: str) -> FuncArgsType:\n    from urllib.parse import urlparse\n\n    url = ''\n    try:\n        url = python_string(rest)\n        tokens = urlparse(url)\n        if not all(\n            (\n                tokens.scheme,\n                tokens.netloc,\n            )\n        ):\n            raise ValueError('Invalid URL')\n    except Exception:\n        log_error('Ignoring invalid URL string: ' + rest)\n    return func, (url,)\n\n\n@func_with_args('goto_tab')\ndef goto_tab_parse(func: str, rest: str) -> FuncArgsType:\n    n = int(rest)\n    if n < 0:\n        n += 1  # goto_tab subtracts 1 from its argument, this maps both zero and -1 to previous tab for backwards compat.\n    return func, (n,)\n\n\n@func_with_args('detach_window')\ndef detach_window_parse(func: str, rest: str) -> FuncArgsType:\n    if rest not in ('new', 'new-tab', 'new-tab-left', 'new-tab-right', 'ask', 'tab-prev', 'tab-left', 'tab-right'):\n        log_error(f'Ignoring invalid detach_window argument: {rest}')\n        rest = 'new'","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/options/utils.py#L143-L179","documentation":"open_url_parse is a func_with_args handler for the launch/open_url action in mouse/map mappings. urlparse is applied to the URL; if the result lacks a scheme or netloc, ValueError('Invalid URL') is raised — but the handler catches it, logs 'Ignoring invalid URL string: ...' and returns the partial URL anyway.","triggerScenarios":"A config line like `mouse_map left click ungrabbed open_url foo` (no scheme/host), or a URL string that urlparse cannot decompose into scheme+netloc. The error is logged and the string is still passed to the handler.","commonSituations":"Hand-writing mouse_map/launch URL actions with a bare hostname or relative path; trailing characters after the URL; the error appears in kitty's error log while browsing despite 'working' configs.","solutions":["Include a full URL with scheme and host, e.g. https://example.com","Check kitty's log (Ctrl+Shift+F1 / kitty.err) for 'Ignoring invalid URL string' and correct the offending map","Quoting the URL in the config avoids tokenization issues"],"exampleFix":"# before\nmouse_map left click ungrabbed open_url example.com\n# after\nmouse_map left click ungrabbed open_url https://example.com","handlingStrategy":"fallback","validationCode":"from urllib.parse import urlparse\nu = urlparse(candidate)\nif not (u.scheme and u.netloc):\n    candidate = 'https://' + candidate  # normalize before use","typeGuard":"def is_valid_url(v: str) -> bool:\n    u = urlparse(v)\n    return bool(u.scheme and u.netloc)","tryCatchPattern":"try:\n    u = urlparse(v)\n    assert u.scheme and u.netloc\nexcept Exception:\n    log.warning('ignoring invalid URL: %s', v)\n    u = None","preventionTips":["Always write URLs with scheme and host in map/launch actions","Check kitty's error log for 'Ignoring invalid URL string' after config changes"],"tags":["kitty","config","url","parse-warning","mouse-map"],"backgroundTag":"url-parse-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}