mvanhorn/last30days-skill · critical · SystemExit

last30days v3 requires Python {req}+.\nDetected Python {majo

Error message

last30days v3 requires Python {req}+.\nDetected Python {major}.{minor}.{micro}.\nInstall with:\n  Mac:     brew install python@{req}\n  Windows: winget install Python.Python.{req}\n  Linux:   sudo apt install python{req}  (or pyenv install {req})\nThen rerun: python{req} <path-to-script> setup\n

What it means

A hard Python-version gate executed at import time in last30days.py: if the running interpreter's (major, minor) is below MIN_PYTHON (3.12 per the repo docs), it prints a platform-specific install recipe to stderr and raises SystemExit(1). No code in the skill runs at all on older interpreters.

Source

Thrown at skills/last30days/scripts/last30days.py:41


def ensure_supported_python(version_info: tuple[int, int, int] | object | None = None) -> None:
    if version_info is None:
        version_info = sys.version_info
    major, minor, micro = tuple(version_info[:3])
    if (major, minor) >= MIN_PYTHON:
        return
    req = f"{MIN_PYTHON[0]}.{MIN_PYTHON[1]}"
    sys.stderr.write(
        f"last30days v3 requires Python {req}+.\n"
        f"Detected Python {major}.{minor}.{micro}.\n"
        f"Install with:\n"
        f"  Mac:     brew install python@{req}\n"
        f"  Windows: winget install Python.Python.{req}\n"
        f"  Linux:   sudo apt install python{req}  (or pyenv install {req})\n"
        f"Then rerun: python{req} <path-to-script> setup\n"
    )
    raise SystemExit(1)


ensure_supported_python()

if os.name == "nt":
    for stream in (sys.stdout, sys.stderr):
        if hasattr(stream, "reconfigure"):
            stream.reconfigure(encoding="utf-8", errors="replace")

SCRIPT_DIR = Path(__file__).parent.resolve()
sys.path.insert(0, str(SCRIPT_DIR))

from lib import competitors as competitors_mod, corpus, dates, discovery_handoff, env, freshness, html_render, http, permission_preflight, pipeline, registers, render, schema, ui

_child_pids: set[int] = set()
_child_pids_lock = threading.Lock()

View on GitHub (pinned to c7460f6114)

Solutions

  1. Re-run with an explicit 3.12+ interpreter: python3.12 scripts/last30days.py setup (exact command is printed in the message).
  2. Install per the printed platform recipe: brew install python@3.12 / winget install Python.Python.3.12 / apt or pyenv install 3.12.
  3. Recreate the project venv from the new interpreter (uv venv --python 3.12) so subsequent runs inherit it.
  4. In cron/systemd/agent configs, hardcode the 3.12+ binary path instead of bare 'python3'.

Example fix

# before
python3 scripts/last30days.py "topic"

# after
python3.12 scripts/last30days.py "topic"
Defensive patterns

Strategy: validation

Validate before calling

import sys
if sys.version_info < (3, 12):
    sys.exit('this tool requires Python 3.12+; invoke with python3.12')

Prevention

When it happens

Trigger: Invoking scripts/last30days.py with python3.11 or older: 'python3 scripts/last30days.py ...' on a system whose default python3 predates 3.12, or a venv created from an old interpreter. ensure_supported_python() runs before anything else, so the very first command fails.

Common situations: macOS system python (3.9); Ubuntu 20.04/22.04 default python3; a cron/CI image pinned to an older Python; harness shims invoking 'python' instead of 'python3.12'.

Related errors


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/15649dd676e1ab7c. Report an issue: GitHub.