google/tsunami-security-scanner · error · ValueError

Value cannot be None.

Error message

Value cannot be None.

What it means

HTTPHeaders.add_header validates that both the header name and value are non-None before storing them in raw_headers. This library throws it to prevent None from leaking into the raw headers dict, which would break downstream HTTP request serialization and header canonicalization.

Solutions

  1. Inspect the call site and find which of name/value is None before calling add_header
  2. Guard the call: only call add_header when both name and value are truthy strings
  3. Provide a default (e.g. value or '') or skip the header entirely if it is genuinely optional
  4. Coerce values loaded from config/env with str() and an explicit None check

Example fix

// before
builder.add_header('Authorization', get_token())  # get_token() may return None
// after
token = get_token()
if token is not None:
  builder.add_header('Authorization', token)
Defensive patterns

Strategy: validation

Validate before calling

def safe_add_header(builder, name, value):
    if name is None or value is None:
        return False
    builder.add_header(name, value)
    return True

Type guard

def is_valid_header_pair(name, value) -> bool:
    return isinstance(name, str) and isinstance(value, str) and bool(name) and bool(value)

Try / catch

try:
    builder.add_header(name, value)
except ValueError as e:
    logging.warning('Skipping invalid header: %s', e)

Prevention

When it happens

Trigger: Calling add_header(name=None, value='x') or add_header('X-Foo', None) while building an HttpRequest's headers, typically when the header value comes from a variable that was never assigned or a function that returned None.

Common situations: Dynamically built header maps where an optional lookup (e.g. dict.get, env var read, token fetch) returned None; refactored code paths where a default value was removed; passing a config field that is unset.

Related errors


AI-assisted analysis of google/tsunami-security-scanner@363ba87b35 (2026-09-13). Data as JSON: /api/errors/4b38da9ef0c0a0dc. Report an issue: GitHub.

Appendix: source

Thrown at plugin_server/py/common/net/http/http_headers.py:94

    """Add HTTP header to headers object.

    Args:
      name: HTTP header field name
      value: HTTP header value
      canonicalize: Optional boolean to normalize header or not. Default is
        True.

    Returns:
      The builder object.

    Raises:
      ValueError: If name or value is None. If header name or value pair does
      not comply with standards.
    """
    if name is None:
      raise ValueError('Name cannot be None.')
    if value is None:
      raise ValueError('Value cannot be None.')
    if canonicalize:
      name = self._canonicalize_header_name(name, value)
    self.http_headers.raw_headers[name].append(value)
    return self

  def _canonicalize_header_name(self, name, value) -> str:
    if not self._is_legal_header_name(name):
      raise ValueError('Illegal header name %s.' % name)
    if not self._is_legal_header_value(value):
      raise ValueError('Illegal header value %s.' % value)
    return _canonicalize(name)

  def _is_legal_header_name(self, name: str) -> bool:
    return bool(re.fullmatch(self.HEADER_NAME_MATCHER, name))

  def _is_legal_header_value(self, value: str) -> bool:
    return bool(re.fullmatch(self.HEADER_VALUE_MATCHER, value))

View on GitHub (pinned to 363ba87b35)