{"record":{"id":"5e0ea0d47892d7cb","repo":"bmad-code-org/BMAD-METHOD","slug":"error-python-3-11-is-required-stdlib-tomllib-5e0ea0","errorCode":null,"errorMessage":"error: Python 3.11+ is required (stdlib `tomllib` not found).","messagePattern":"error: Python 3\\.11\\+ is required \\(stdlib `tomllib` not found\\)\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"critical","filePath":"src/scripts/resolve_customization.py","lineNumber":21,"sourceCode":"# requires-python = \">=3.11\"\n# ///\n\"\"\"Resolve a skill's default, team, and user TOML customization layers.\"\"\"\n\nimport argparse\nimport json\nimport sys\nfrom pathlib import Path\n\n# Installed scripts are consumer files, not a location for interpreter caches.\nsys.dont_write_bytecode = True\n\ntry:\n    from config_utils import ConfigError, load_customization\nexcept ModuleNotFoundError as error:\n    if error.name != \"tomllib\":\n        raise\n    sys.stderr.write(\"error: Python 3.11+ is required (stdlib `tomllib` not found).\\n\")\n    raise SystemExit(3) from None\n\n\n_MISSING = object()\n\n\ndef find_project_root(start: Path) -> Path | None:\n    current = start.resolve()\n    while True:\n        if (current / \"_bmad\").exists() or (current / \".git\").exists():\n            return current\n        if current.parent == current:\n            return None\n        current = current.parent\n\n\ndef extract_key(data, dotted_key: str):\n    current = data\n    for part in dotted_key.split(\".\"):","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/src/scripts/resolve_customization.py#L3-L39","documentation":"Identical mechanism to its sibling in resolve_config.py: a runtime interpreter-version guard. This script imports `load_customization` from the local `config_utils` module, which performs `import tomllib` (config_utils.py:5). `tomllib` is standard-library only on Python 3.11+. On older interpreters the import raises `ModuleNotFoundError(name='tomllib')`; the wrapper matches `error.name == 'tomllib'`, writes the same one-line message, and exits with `SystemExit(3)`. The guard exists because the project has no `pyproject.toml` / `requires-python` declaration, so this import-time check is the only enforcement of the minimum interpreter.","triggerScenarios":"Invoking `resolve_customization.py` (directly or via a wrapper) with an interpreter where `sys.version_info < (3, 11)` — e.g. `python3.10 src/scripts/resolve_customization.py`, or a `#!/usr/bin/env python3` shebang resolving to an older `python3` on PATH; running the customization-resolution test suite under the wrong interpreter; a pre-3.11 venv; a CI image pinned to 3.9/3.10. The error is raised at import time before any `_bmad`/`.git` project-root lookup or customization file is touched, so customization-file contents are NOT a cause.","commonSituations":"1) Default `python3` on older LTS distros (Ubuntu 20.04 → 3.8, Debian 11 → 3.9) satisfying the shebang. 2) A venv built from a pre-3.11 base interpreter. 3) pyenv / asdf / mise shims still pointing at an older Python after an upgrade. 4) CI matrix that still lists 3.9/3.10, or a Docker base like `python:3.10-slim`. 5) A poetry/uv/conda env materialised against an older default Python. 6) A shell alias or PATH ordering that shadows the 3.11+ interpreter with an older one.","solutions":["Run the script with Python 3.11+: `python3.11 src/scripts/resolve_customization.py` (or `python3.12`). Confirm with `python3 --version` first.","Recreate the virtualenv on a 3.11+ base: `python3.12 -m venv .venv && source .venv/bin/activate`, then re-run.","Pin the interpreter via your version manager: `pyenv local 3.12` / `mise use python@3.12` / `asdf local python 3.12.x`.","If locked to < 3.11 and upgrading is impossible, install the `tomli` backport and add `if sys.version_info < (3,11): import tomli as tomllib` in config_utils.py — only with the project owner's sign-off, since this is a code change, not configuration.","On CI, raise the setup-python version: `python-version: '3.11'` or newer, or switch the Docker base to `python:3.11-slim`+."],"exampleFix":"# before — shebang floats to whatever 'python3' resolves to\n#!/usr/bin/env python3\n\n# after — pin to a 3.11+ interpreter explicitly\n#!/usr/bin/env python3.12\n\n# or, in CI (.github/workflows/*.yml)\n# before\n- uses: actions/setup-python@v5\n  with:\n    python-version: '3.10'\n# after\n- uses: actions/setup-python@v5\n  with:\n    python-version: '3.12'","handlingStrategy":"validation","validationCode":"import sys\n\nMIN_PY = (3, 11)\n\nif sys.version_info < MIN_PY:\n    sys.exit(\n        f\"error: Python {MIN_PY[0]}.{MIN_PY[1]}+ is required \"\n        f\"(running {sys.version_info.major}.{sys.version_info.minor}).\"\n    )\n\n# Safe to invoke resolve_customization / config_utils here.\nimport subprocess, sys\nsubprocess.run([sys.executable, \"src/scripts/resolve_customization.py\"], check=True)","typeGuard":null,"tryCatchPattern":"# SystemExit(3) fires at import time; catch it only at a subprocess boundary,\n# never around the import, or you hide a genuinely broken environment.\nimport subprocess, sys\n\nproc = subprocess.run(\n    [sys.executable, \"src/scripts/resolve_customization.py\"],\n    capture_output=True, text=True,\n)\nif proc.returncode == 3 and \"tomllib\" in proc.stderr:\n    raise RuntimeError(\n        \"resolve_customization needs Python 3.11+; current interpreter is \"\n        f\"{sys.version.split()[0]}.\"\n    )\nraise SystemExit(proc.returncode)","preventionTips":["Pin the project interpreter explicitly: add a `.python-version` file (pyenv/asdf/mise) or `requires-python = '>=3.11'` in a `pyproject.toml` so the requirement is enforced at install time.","Invoke the script via the venv's absolute interpreter (`$VIRTUAL_ENV/bin/python` / `python3.12`) rather than a bare `python3` whose meaning varies per machine.","Add a preflight assertion in any orchestrator: `assert sys.version_info >= (3, 11), 'Python 3.11+ required (tomllib).'`.","Lock CI to a 3.11+ matrix and fail fast on older versions; do not ship green-on-3.10 and broken-on-3.12 (or vice versa).","State the minimum interpreter in the README beside the install command so the venv is built with the right base."],"tags":["python","python-version","tomllib","dependency","startup","interpreter"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}