{"record":{"id":"8a9fe8b3383f35bf","repo":"headroomlabs-ai/headroom","slug":"invalid-tool-injection-sticky-env-normalized-r","errorCode":null,"errorMessage":"Invalid {TOOL_INJECTION_STICKY_ENV}={normalized!r}; expected 'enabled' or 'disabled'","messagePattern":"Invalid (.+?)=(.+?); expected 'enabled' or 'disabled'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/proxy/tool_injection_policy.py","lineNumber":23,"sourceCode":"from typing import Literal, cast\n\nTOOL_INJECTION_STICKY_ENV = \"HEADROOM_TOOL_INJECTION_STICKY\"\nToolInjectionStickyMode = Literal[\"enabled\", \"disabled\"]\nTOOL_INJECTION_STICKY_DEFAULT: ToolInjectionStickyMode = \"enabled\"\n\nTOOL_TRACKER_MAX_SESSIONS_ENV = \"HEADROOM_TOOL_TRACKER_MAX_SESSIONS\"\nTOOL_TRACKER_MAX_SESSIONS_DEFAULT = 1000\n\n\ndef resolve_tool_injection_sticky_mode(raw: str | None) -> ToolInjectionStickyMode:\n    \"\"\"Resolve memory-tool injection stickiness mode from an environment value.\"\"\"\n\n    normalized = (raw or \"\").strip().lower()\n    if not normalized:\n        return TOOL_INJECTION_STICKY_DEFAULT\n    if normalized in (\"enabled\", \"disabled\"):\n        return cast(ToolInjectionStickyMode, normalized)\n    raise ValueError(\n        f\"Invalid {TOOL_INJECTION_STICKY_ENV}={normalized!r}; expected 'enabled' or 'disabled'\"\n    )\n\n\ndef resolve_tool_tracker_max_sessions(raw: str | None) -> int:\n    \"\"\"Resolve the positive LRU session bound for tool injection tracking.\"\"\"\n\n    normalized = (raw or \"\").strip()\n    if not normalized:\n        return TOOL_TRACKER_MAX_SESSIONS_DEFAULT\n    try:\n        value = int(normalized)\n    except ValueError as exc:\n        raise ValueError(\n            f\"Invalid {TOOL_TRACKER_MAX_SESSIONS_ENV}={normalized!r}; expected positive int\"\n        ) from exc\n    if value <= 0:\n        raise ValueError(","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/proxy/tool_injection_policy.py#L5-L41","documentation":"Raised by resolve_tool_injection_sticky_mode() when the HEADROOM_TOOL_INJECTION_STICKY environment variable is set to a value other than 'enabled' or 'disabled' (after trimming and lowercasing). The library validates this env var strictly because sticky mode controls whether memory-tool injection persists across requests. An empty/unset value is allowed and falls back to the default; only non-empty invalid strings raise.","triggerScenarios":"Calling resolve_tool_injection_sticky_mode(raw) with e.g. 'true', 'on', '1', 'yes' — or setting HEADROOM_TOOL_INJECTION_STICKY=true in the environment before proxy startup. Any non-empty string that is not 'enabled'/'disabled' after .strip().lower() triggers it.","commonSituations":"Assuming boolean-style env values ('true'/'false', '1'/'0') work; a typo like 'enaabled'; copying a config from another tool that uses 'on'/'off'; leftover value from a previous deployment.","solutions":["Set HEADROOM_TOOL_INJECTION_STICKY to exactly 'enabled' or 'disabled' (case-insensitive, surrounding whitespace is tolerated).","Unset the variable entirely to accept the default behavior.","If you need a boolean-style value, map it yourself before passing: raw = 'enabled' if flag else 'disabled'."],"exampleFix":"# before\nHEADROOM_TOOL_INJECTION_STICKY=true\n\n# after\nHEADROOM_TOOL_INJECTION_STICKY=enabled","handlingStrategy":"validation","validationCode":"from headroom.proxy.tool_injection_policy import resolve_tool_injection_sticky_mode\n\nraw = os.environ.get('HEADROOM_TOOL_INJECTION_STICKY')\nnormalized = (raw or '').strip().lower()\nif normalized and normalized not in ('enabled', 'disabled'):\n    raise SystemConfigError(f'bad sticky mode: {raw!r}')\nmode = resolve_tool_injection_sticky_mode(raw)","typeGuard":"def is_valid_sticky_mode(raw: str | None) -> bool:\n    normalized = (raw or '').strip().lower()\n    return normalized == '' or normalized in ('enabled', 'disabled')","tryCatchPattern":"try:\n    mode = resolve_tool_injection_sticky_mode(raw)\nexcept ValueError as e:\n    logger.error('config error: %s', e)\n    raise SystemExit(2) from e  # fail fast at startup, not per-request","preventionTips":["Document the allowed values ('enabled'/'disabled') next to the env var in your deployment manifest.","Validate environment configuration once at process startup and exit early on invalid values.","Add a config lint step to CI that checks env var values against a schema."],"tags":["configuration","environment","validation","proxy"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}