{"record":{"id":"8e85901878648fc5","repo":"headroomlabs-ai/headroom","slug":"wrap-proxy-timeout-env-must-be-a-positive-integ","errorCode":null,"errorMessage":"{_WRAP_PROXY_TIMEOUT_ENV} must be a positive integer number of seconds (got {raw!r})","messagePattern":"(.+?) must be a positive integer number of seconds \\(got (.+?)\\)","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"headroom/cli/wrap.py","lineNumber":537,"sourceCode":"def _default_wrap_proxy_timeout_seconds() -> int:\n    \"\"\"Return the default wrap proxy startup timeout for this environment.\"\"\"\n\n    if _ml_wrap_extras_detected():\n        return _WRAP_PROXY_TIMEOUT_ML_DEFAULT_SECONDS\n    return _WRAP_PROXY_TIMEOUT_DEFAULT_SECONDS\n\n\ndef _resolve_wrap_proxy_timeout_seconds() -> int:\n    \"\"\"Resolve the wrap proxy readiness timeout from env or defaults.\"\"\"\n\n    raw = os.environ.get(_WRAP_PROXY_TIMEOUT_ENV, \"\").strip()\n    if not raw:\n        return _default_wrap_proxy_timeout_seconds()\n\n    try:\n        timeout_seconds = int(raw)\n    except ValueError:\n        raise RuntimeError(\n            f\"{_WRAP_PROXY_TIMEOUT_ENV} must be a positive integer number of seconds (got {raw!r})\"\n        ) from None\n    if timeout_seconds <= 0:\n        raise RuntimeError(\n            f\"{_WRAP_PROXY_TIMEOUT_ENV} must be a positive integer number of seconds (got {raw!r})\"\n        )\n    return timeout_seconds\n\n\ndef _print_telemetry_notice() -> None:\n    \"\"\"Print a telemetry notice when anonymous telemetry is enabled.\n\n    Respects the HEADROOM_TELEMETRY and HEADROOM_TELEMETRY_WARN feature flags.\n    Does nothing when telemetry or warnings are disabled.\n    \"\"\"\n    from headroom.telemetry.beacon import format_telemetry_notice\n\n    notice = format_telemetry_notice(prefix=\"  \")","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/cli/wrap.py#L519-L555","documentation":"The wrap proxy readiness timeout is configurable via the HEADROOM_WRAP_PROXY_TIMEOUT env var (referenced by _WRAP_PROXY_TIMEOUT_ENV). _resolve_wrap_proxy_timeout_seconds parses it strictly: it must be a base-10 integer greater than zero. Non-numeric text ('30s', '1.5', '') or values <= 0 raise RuntimeError naming the variable and echoing the offending raw value; empty/unset falls back to a default and never raises.","triggerScenarios":"Exporting HEADROOM_WRAP_PROXY_TIMEOUT with a unit suffix ('90s'), a float ('1.5'), a negative number, or stray whitespace/characters ('60 '), then running `headroom wrap ...` which calls this resolver.","commonSituations":"Copy-pasting timeout values with units from docs or docker-compose examples ('30s' is valid YAML duration syntax but not here); CI env matrices setting 0 to 'disable' the timeout; shell quoting artifacts.","solutions":["Set a plain positive integer: export HEADROOM_WRAP_PROXY_TIMEOUT=120","Remove unit suffixes and decimals — '90' not '90s', '2' not '2.0'","To get the default behavior, unset the variable entirely rather than setting 0","If you intended a longer startup window for ML extras, raise the integer (defaults are larger when ML extras are detected)"],"exampleFix":"# before\nexport HEADROOM_WRAP_PROXY_TIMEOUT=90s\nheadroom wrap -- claude\n# RuntimeError: ... must be a positive integer number of seconds (got '90s')\n\n# after\nexport HEADROOM_WRAP_PROXY_TIMEOUT=90\nheadroom wrap -- claude","handlingStrategy":"validation","validationCode":"import os\n\nraw = os.environ.get(\"HEADROOM_WRAP_PROXY_TIMEOUT\", \"\").strip()\nif raw:\n    try:\n        v = int(raw)\n        assert v > 0, \"must be > 0\"\n    except (ValueError, AssertionError):\n        raise SystemExit(\n            \"HEADROOM_WRAP_PROXY_TIMEOUT must be a positive integer (e.g. 90, not '90s')\"\n        )","typeGuard":"def valid_timeout(raw: str | None) -> bool:\n    if raw is None or not raw.strip():\n        return True  # unset falls back to defaults\n    try:\n        return int(raw.strip()) > 0\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    run_wrap_command()\nexcept RuntimeError as e:\n    if \"HEADROOM_WRAP_PROXY_TIMEOUT\" in str(e):\n        os.environ.pop(\"HEADROOM_WRAP_PROXY_TIMEOUT\", None)  # fall back to default\n        run_wrap_command()\n    else:\n        raise","preventionTips":["Use bare integers in env files and CI variable matrices — no units, no floats","Unset the variable entirely instead of setting 0 to get default behavior","Validate the variable in bootstrap scripts before invoking headroom wrap"],"tags":["cli","wrap","environment-variable","configuration","runtimeerror"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}