arduino/Arduino · error · ValueError
cannot encode objects that are not 2-tuples
Error message
cannot encode objects that are not 2-tuples
What it means
utils.from_key_val_list converts request data into an OrderedDict. It rejects scalar values (str, bytes, bool, int) because they cannot be interpreted as key/value pairs, raising ValueError so users get a clear message instead of a cryptic failure later during URL-encoding.
Source
Thrown at arduino-core/src/processing/app/i18n/python/requests/utils.py:113
def from_key_val_list(value):
"""Take an object and test to see if it can be represented as a
dictionary. Unless it can not be represented as such, return an
OrderedDict, e.g.,
::
>>> from_key_val_list([('key', 'val')])
OrderedDict([('key', 'val')])
>>> from_key_val_list('string')
ValueError: need more than 1 value to unpack
>>> from_key_val_list({'key': 'val'})
OrderedDict([('key', 'val')])
"""
if value is None:
return None
if isinstance(value, (str, bytes, bool, int)):
raise ValueError('cannot encode objects that are not 2-tuples')
return OrderedDict(value)
def to_key_val_list(value):
"""Take an object and test to see if it can be represented as a
dictionary. If it can be, return a list of tuples, e.g.,
::
>>> to_key_val_list([('key', 'val')])
[('key', 'val')]
>>> to_key_val_list({'key': 'val'})
[('key', 'val')]
>>> to_key_val_list('string')
ValueError: cannot encode objects that are not 2-tuples.
"""
if value is None:View on GitHub (pinned to a0df6e0e83)
Solutions
- Pass a dict or list of 2-tuples: params={'q': 'x'} or data=[('k','v')].
- If you meant a raw query string, use the URL itself ('...?q=x') rather than params.
- Wrap scalars appropriately: data={'value': 5}, not data=5.
- Use to_key_val_list/from_key_val_list defensively in your own code with a try/except ValueError.
Example fix
// before
requests.get(url, params='q=test') # ValueError
// after
requests.get(url, params={'q': 'test'}) Defensive patterns
Strategy: validation
Validate before calling
def coerce_params(v):
if v is None or isinstance(v, (dict, list, tuple)):
return v
raise ValueError('params/data must be a dict or list of 2-tuples, got %r' % (v,))
params = coerce_params(raw_params) Type guard
from collections.abc import Mapping
def is_key_val(v) -> bool:
if isinstance(v, (str, bytes, bool, int)):
return False
if isinstance(v, Mapping):
return True
return isinstance(v, (list, tuple)) and all(isinstance(t, (list, tuple)) and len(t) == 2 for t in v) Try / catch
try:
resp = requests.get(url, params=p)
except ValueError as e:
if 'not 2-tuples' in str(e):
raise TypeError('params must be dict or list of 2-tuples, got %s' % type(p).__name__) from e
raise Prevention
- Always pass dicts (or 2-tuple lists) to params/data/headers.
- Watch for scalars reaching params via variables that also hold query strings.
- Put raw query strings in the URL itself, not in params.
- Validate request-building inputs in wrapper layers.
When it happens
Trigger: Passing params='foo', data=5, headers=True, or similar scalar instead of a dict/list of 2-tuples to requests APIs (session.request, merge_environment_settings, merge_kwargs); passing a dict-like of non-2-tuples.
Common situations: Confusing params with a plain string query; accidentally passing a boolean/int (e.g. data=page_count); copy-paste where a variable holding a scalar is used where a dict was intended.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- You can only send PreparedRequests.
- Classes extending RequestMethods must implement their own ``
- stream_decompress mode must be gzip or deflate
- SSLError(e)
- MaxRetryError(self, url, e)
AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06).
Data as JSON: /api/errors/a23beceac30afaef.
Report an issue: GitHub.