{"record":{"id":"d031446539cf6a91","repo":"BerriAI/litellm","slug":"max-bytes-per-call-must-be-0-0-disables-the-ca","errorCode":null,"errorMessage":"max_bytes_per_call must be >= 0 (0 disables the cap; positive values enforce it)","messagePattern":"max_bytes_per_call must be >= 0 \\(0 disables the cap; positive values enforce it\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/compresr/compresr.py","lineNumber":547,"sourceCode":"        self.compression_model = model or DEFAULT_COMPRESSION_MODEL\n        self.target_compression_ratio = (\n            DEFAULT_TARGET_COMPRESSION_RATIO if target_compression_ratio is None else target_compression_ratio\n        )\n        self.coarse = True if coarse is None else coarse\n        self.min_chars_to_compress = (\n            DEFAULT_MIN_CHARS_TO_COMPRESS if min_chars_to_compress is None else min_chars_to_compress\n        )\n        self.compress_tool_outputs = True if compress_tool_outputs is None else compress_tool_outputs\n        self.compress_system = False if compress_system is None else compress_system\n        self.compress_history = False if compress_history is None else compress_history\n        self.compress_last_user = False if compress_last_user is None else compress_last_user\n        self.enable_retrieval = True if enable_retrieval is None else enable_retrieval\n        self.unreachable_fallback: Literal[\"fail_closed\", \"fail_open\"] = (\n            \"fail_open\" if unreachable_fallback == \"fail_open\" else \"fail_closed\"\n        )\n        self.max_bytes_per_call = _DEFAULT_MAX_BYTES_PER_CALL if max_bytes_per_call is None else max_bytes_per_call\n        if self.max_bytes_per_call < 0:\n            raise ValueError(\"max_bytes_per_call must be >= 0 (0 disables the cap; positive values enforce it)\")\n        self.allow_bypass_header = False if allow_bypass_header is None else allow_bypass_header\n        # Dynamic (adaptive) compression — latte_v2 only, on by default: the server\n        # picks the ratio per input instead of honoring target_compression_ratio.\n        self.dynamic = True if dynamic is None else dynamic\n        self.dynamic_min_ratio = dynamic_min_ratio\n        self.dynamic_max_ratio = dynamic_max_ratio\n        # Passthrough of extra compression params forwarded verbatim, so a new\n        # Compresr feature works without changing this guardrail. Named fields win;\n        # request-content fields are stripped.\n        reserved_keys: Final = _RESERVED_COMPRESSION_PARAM_KEYS.intersection(compression_params or {})\n        if reserved_keys:\n            verbose_proxy_logger.warning(\n                \"Compresr: ignoring reserved compression_params keys %s\", sorted(reserved_keys)\n            )\n        self.compression_params: dict[str, object] = {\n            k: v for k, v in (compression_params or {}).items() if k not in _RESERVED_COMPRESSION_PARAM_KEYS\n        }\n        self.async_handler = get_async_httpx_client(","sourceCodeStart":529,"sourceCodeEnd":565,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/compresr/compresr.py#L529-L565","documentation":"ValueError raised in the Compresr guardrail constructor when max_bytes_per_call is negative. The parameter controls how many bytes of original prompt content the guardrail retains per call (0 disables the cap; the default is _DEFAULT_MAX_BYTES_PER_CALL); a negative value is meaningless, so config validation rejects it immediately at startup.","triggerScenarios":"Passing max_bytes_per_call: -1 (or any negative number) in the guardrail litellm_params — often a typo, a mistaken '0 means unlimited, so -1 must mean something' assumption, or a templated/env-derived value computing to a negative.","commonSituations":"Operators copying example configs and changing the number; arithmetic in config generation (e.g., default - buffer) producing negatives; confusing '0 disables the cap' semantics with sentinel negative values.","solutions":["Use 0 to disable the cap or a positive byte count to enforce it.","If the value comes from an env var or template, add a max(0, int(...)) guard before it reaches the config.","Reload the proxy after correcting the value."],"exampleFix":"# before\nlitellm_params:\n  guardrail: compresr\n  max_bytes_per_call: -1\n\n# after — cap disabled explicitly\nlitellm_params:\n  guardrail: compresr\n  max_bytes_per_call: 0","handlingStrategy":"validation","validationCode":"raw = litellm_params.get(\"max_bytes_per_call\")\nif raw is not None:\n    v = int(raw)\n    assert v >= 0, f\"max_bytes_per_call must be >= 0 (0 disables cap); got {v}\"","typeGuard":"from typing import Any\ndef is_non_negative_int_or_none(v: Any) -> bool:\n    return v is None or (isinstance(v, int) and not isinstance(v, bool) and v >= 0)","tryCatchPattern":null,"preventionTips":["Remember the semantics: 0 disables the cap; there is no negative sentinel.","Clamp computed values: max_bytes_per_call = max(0, computed).","Lint numeric guardrail params in CI with the same bounds the constructor enforces."],"tags":["litellm","guardrails","compresr","configuration","validation","numeric-limits"],"backgroundTag":"config-validation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}