{"record":{"id":"f0e750be33fe7593","repo":"headroomlabs-ai/headroom","slug":"pyproject-toml-must-contain-one-exact-ruff-pin-in","errorCode":null,"errorMessage":"pyproject.toml must contain one exact Ruff pin in project.optional-dependencies.dev","messagePattern":"pyproject\\.toml must contain one exact Ruff pin in project\\.optional-dependencies\\.dev","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scripts/verify-ruff-version.py","lineNumber":37,"sourceCode":"WORKFLOW_INSTALL_REFERENCE = \"steps.ruff-version.outputs.version\"\n\n\ndef _load_toml(path: Path) -> dict[str, Any]:\n    with path.open(\"rb\") as file:\n        return cast(dict[str, Any], tomllib.load(file))\n\n\ndef _authoritative_version() -> str:\n    dependencies = _load_toml(ROOT / \"pyproject.toml\")[\"project\"][\"optional-dependencies\"][\"dev\"]\n    ruff_requirements = [\n        requirement for requirement in dependencies if requirement.startswith(\"ruff\")\n    ]\n    if len(ruff_requirements) != 1:\n        raise ValueError(f\"expected one Ruff dev dependency, found {ruff_requirements!r}\")\n\n    match = re.fullmatch(r\"ruff==([^;,\\s]+)\", ruff_requirements[0])\n    if match is None:\n        raise ValueError(\n            \"pyproject.toml must contain one exact Ruff pin in project.optional-dependencies.dev\"\n        )\n    return match.group(1)\n\n\ndef _locked_version() -> str:\n    packages = _load_toml(ROOT / \"uv.lock\")[\"package\"]\n    versions = [str(package[\"version\"]) for package in packages if package[\"name\"] == \"ruff\"]\n    if len(versions) != 1:\n        raise ValueError(f\"expected one locked Ruff package, found {versions!r}\")\n    return versions[0]\n\n\ndef _pre_commit_version() -> str:\n    lines = (ROOT / \".pre-commit-config.yaml\").read_text(encoding=\"utf-8\").splitlines()\n    for index, line in enumerate(lines):\n        if line.strip() != f\"- repo: {RUFF_PRE_COMMIT_REPO}\":\n            continue","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/scripts/verify-ruff-version.py#L19-L55","documentation":"After finding the single Ruff dev dependency, verify-ruff-version.py requires it to be an exact pin matching `ruff==<version>` exactly (fullmatch, no range, no extras, no environment markers). Loose constraints like `ruff>=0.4` or `ruff` break the invariant that pyproject.toml is the single source of truth for the Ruff version.","triggerScenarios":"Changing the pin to `>=`, `~=`, `!=`, or adding a marker/extras to the requirement string; a dependency bot relaxing the pin; hand-merging a conflict resolution that drops the `==`.","commonSituations":"Renovate/Dependabot range updates replacing `==` with `>=`; developers loosening the pin to test a pre-release; merge conflicts in pyproject.toml.","solutions":["Restore the exact pin form: `ruff==X.Y.Z` with no spaces, markers, or extras.","To upgrade Ruff, change the version on the right of `==` (and let the script verify uv.lock and pre-commit agree).","Check for stray characters — the fullmatch rejects `ruff == 0.5.0` and `ruff==0.5 ; python_version>='3.9'` alike."],"exampleFix":"# pyproject.toml - before\n[project.optional-dependencies]\ndev = [\"ruff>=0.5.0\"]\n\n# after\n[project.optional-dependencies]\ndev = [\"ruff==0.5.0\"]","handlingStrategy":"validation","validationCode":"import re\n\ndef is_exact_ruff_pin(requirement: str) -> bool:\n    return re.fullmatch(r\"ruff==([^;,\\s]+)\", requirement) is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the Ruff dev dependency an exact `ruff==X.Y.Z` string with no markers or spaces.","Configure dependency bots to keep exact pins (pinning enabled) rather than widening ranges.","When upgrading Ruff, update pin, uv.lock, and pre-commit rev in one change and run the verify script."],"tags":["ruff","pyproject","version-pinning","linting"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}