{"record":{"id":"2123a5f0f7e2e7b9","repo":"CloakHQ/CloakBrowser","slug":"invalid-browser-version-pin-use-a-full-numeric-ch-2123a5","errorCode":null,"errorMessage":"Invalid browser version pin. Use a full numeric Chromium version, e.g. '148.0.7778.215.2'.","messagePattern":"Invalid browser version pin\\. Use a full numeric Chromium version, e\\.g\\. '148\\.0\\.7778\\.215\\.2'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"cloakbrowser/config.py","lineNumber":131,"sourceCode":"    )\n    return \"preview\" if raw.strip().lower() == \"preview\" else \"stable\"\n\n\ndef normalize_requested_version(version: str | None = None) -> str | None:\n    \"\"\"Return an explicit Chromium version pin from arg/env, or None.\n\n    The explicit argument wins over CLOAKBROWSER_VERSION. Only numeric dotted\n    versions are accepted because the value is interpolated into cache paths and\n    download URLs.\n    \"\"\"\n    raw = version if version is not None else os.environ.get(\"CLOAKBROWSER_VERSION\")\n    if raw is None:\n        return None\n    normalized = raw.strip()\n    if not normalized:\n        return None\n    if not _VERSION_PIN_RE.fullmatch(normalized):\n        raise ValueError(\n            \"Invalid browser version pin. Use a full numeric Chromium version, \"\n            \"e.g. '148.0.7778.215.2'.\"\n        )\n    return normalized\n\n\ndef get_chromium_version() -> str:\n    \"\"\"Return the Chromium version for the current platform.\"\"\"\n    tag = get_platform_tag()\n    return PLATFORM_CHROMIUM_VERSIONS.get(tag, CHROMIUM_VERSION)\n\n\ndef get_platform_tag() -> str:\n    \"\"\"Return the platform tag for binary download (e.g. 'linux-x64', 'darwin-arm64').\"\"\"\n    system = platform.system()\n    machine = platform.machine()\n    tag = SUPPORTED_PLATFORMS.get((system, machine))\n    if tag is None:","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/cloakbrowser/config.py#L113-L149","documentation":"normalize_requested_version validates the browser version pin (CLOAKBROWSER_BROWSER_VERSION env var or browser_version argument) against a full numeric Chromium version regex. Anything not matching (e.g. '148', 'latest', 'v148.0...') raises ValueError.","triggerScenarios":"Passing browser_version='148' or setting CLOAKBROWSER_BROWSER_VERSION to a partial, prefixed, or non-numeric string; any call path that resolves a binary (ensure_binary, binary_info, launch, etc.).","commonSituations":"Copying a Chrome version string with a 'v' prefix; assuming short versions work; trailing whitespace is stripped but empty strings and tags like 'beta' are rejected.","solutions":["Use a full 4-part numeric version like '148.0.7778.215.2'","Remove the 'v' prefix and any channel suffix","Unset the env var / omit the argument to use the default version"],"exampleFix":"# before\nensure_binary(browser_version=\"148\")\n# after\nensure_binary(browser_version=\"148.0.7778.215.2\")","handlingStrategy":"validation","validationCode":"import re\nVERSION_RE = re.compile(r\"^\\d+\\.\\d+\\.\\d+\\.\\d+$\")\ndef valid_pin(v: str) -> bool:\n    return bool(VERSION_RE.fullmatch(v.strip()))","typeGuard":"def is_full_version(v: str | None) -> bool:\n    return v is not None and bool(__import__('re').fullmatch(r\"\\d+\\.\\d+\\.\\d+\\.\\d+\", v.strip()))","tryCatchPattern":"try:\n    ensure_binary(browser_version=v)\nexcept ValueError:\n    ensure_binary(browser_version=\"148.0.7778.215.2\")","preventionTips":["Normalize user-supplied versions through a 4-part regex before use","Prefer omitting browser_version unless you truly need a pin"],"tags":["version-pin","validation","config"],"backgroundTag":"invalid-version-string","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}