`master` does not import: `except asyncio.CancelledError, Exception:` in `__main__.py` (SyntaxError on every invocation)

Author: khorma11Created Sep 16, 2026Updated Sep 17, 2026

Summary

theHarvester on current master cannot be run at all. theHarvester/__main__.py line 1394 contains

python
except asyncio.CancelledError, Exception:

which is a SyntaxError in every Python 3 release. Because it is a compile-time error, every entrypoint fails — including --help and --version — so there is no invocation that works.

Reproduction

bash
$ git clone https://github.com/laramies/theHarvester && cd theHarvester
$ python3 -m theHarvester --help
Traceback (most recent call last):
  File "<frozen runpy>", line 194, in _run_module_as_main
  ...
  File ".../theHarvester/__main__.py", line 1394
    except asyncio.CancelledError, Exception:
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: multiple exception types must be parenthesized

Same result for --version and for any -d/-b combination.

Affected

  • master @ 78a78f08 (2026-09-07) — still present
  • Introduced in 77304235 (2026-08-17, "bump ruff to py3.14 and fix all the errors from mypy,ty,pytest and ruff issues"), so master has been unusable for about a month
  • Reproduced on CPython 3.13.15; the syntax is invalid on 3.14 too, so the CI's Python version does not change the outcome

Fix

The mechanical fix is the parentheses:

python
except (asyncio.CancelledError, Exception):

One thing worth a maintainer's judgement rather than a blind parenthesisation: since Python 3.8 asyncio.CancelledError inherits from BaseException, not Exception, so naming it alongside Exception is the only way to catch both — which suggests the intent here was deliberate. But swallowing CancelledError suppresses task cancellation, and in this block that happens whenever best_effort is set (the not best_effort branch re-raises). You may want

python
except asyncio.CancelledError:
    raise
except Exception:
    if not best_effort:
        raise
    return {}, set()

so a cancelled task stays cancelled while a genuine failure is still absorbed. That is a behavioural change, so I have not assumed it.

Why CI appears not to have caught it

.github/workflows/theHarvester.yml runs ruff check, ruff format --check, pytest and ty check, and pyproject.toml excludes only tests and cache directories from ruff, with [tool.ty.src] include = ["theHarvester"] — so an unparseable file in that package would normally fail at least two of those steps.

On 78a78f08 the check-runs attached to the commit are Dependabot, Scorecard analysis and CodeQL Analyze (python) only; there is no TheHarvester Python CI run among them. It may be worth checking whether that workflow is firing on merges to master, since it is the thing that would have stopped this.

Environment

  • macOS, CPython 3.13.15
  • Fresh clone of master, no local modifications (git status clean, file matches HEAD)