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
- Inspect the call site and find which of name/value is None before calling add_header
- Guard the call: only call add_header when both name and value are truthy strings
- Provide a default (e.g. value or '') or skip the header entirely if it is genuinely optional
- 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
- Never pass dict.get() results straight into add_header without a None check
- Coerce config/env-derived header values with explicit str() and default handling
- Add a unit test for every dynamic header path with a missing-value case
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
- Name cannot be None.
- Illegal header name .
- Illegal header value
- Url cannot be None.
- A request body is not allowed for HTTP GET/HEAD request.
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)