python/cpython · error · ValueError
Invalid sign. The first value in the tuple should be an int
Error message
Invalid sign. The first value in the tuple should be an integer; either 0 for a positive number or 1 for a negative number.
What it means
When constructing a Decimal from a 3-element sequence, the first element must be a Python int equal to 0 (positive) or 1 (negative). The isinstance(value[0], int) check also deliberately rejects floats like 1.0 and strings like '1'. This ValueError signals a malformed sign field in the decimal triple.
Source
Thrown at Lib/_pydecimal.py:561
return self
# From an internal working value
if isinstance(value, _WorkRep):
self._sign = value.sign
self._int = str(value.int)
self._exp = int(value.exp)
self._is_special = False
return self
# tuple/list conversion (possibly from as_tuple())
if isinstance(value, (list,tuple)):
if len(value) != 3:
raise ValueError('Invalid tuple size in creation of Decimal '
'from list or tuple. The list or tuple '
'should have exactly three elements.')
# process sign. The isinstance test rejects floats
if not (isinstance(value[0], int) and value[0] in (0,1)):
raise ValueError("Invalid sign. The first value in the tuple "
"should be an integer; either 0 for a "
"positive number or 1 for a negative number.")
self._sign = value[0]
if value[2] == 'F':
# infinity: value[1] is ignored
self._int = '0'
self._exp = value[2]
self._is_special = True
else:
# process and validate the digits in value[1]
digits = []
for digit in value[1]:
if isinstance(digit, int) and 0 <= digit <= 9:
# skip leading zeros
if digits or digit != 0:
digits.append(digit)
else:
raise ValueError("The second value in the tuple must "View on GitHub (pinned to bc6749cc3b)
Solutions
- Normalize the sign to int 0 or 1: sign = 1 if value < 0 else 0
- If the sign arrived as a string from JSON/CSV, convert it explicitly: sign = int(sign_str)
- Validate the triple shape before calling Decimal (see defense below)
Example fix
// before sign = -1 if x < 0 else 0 d = Decimal((sign, digits, exp)) # ValueError for negatives // after sign = 1 if x < 0 else 0 d = Decimal((sign, digits, exp))
Defensive patterns
Strategy: validation
Validate before calling
def normalize_triple(sign, digits, exp):
sign = int(sign)
if sign not in (0, 1):
sign = 1 if sign else 0 # maps -1/other truthy to 1
return (sign, digits, exp) Type guard
def valid_sign(s) -> bool:
return isinstance(s, int) and not isinstance(s, bool) and s in (0, 1) Try / catch
try:
d = Decimal(triple)
except ValueError as e:
if 'Invalid sign' in str(e):
triple = (1 if triple[0] else 0, triple[1], triple[2])
d = Decimal(triple) Prevention
- Use 0/1 sign convention everywhere; never store -1 for negative
- int()-cast sign fields from JSON/CSV at the deserialization boundary
- Remember bool passes the check (True==1); exclude bools if strictness matters
When it happens
Trigger: Decimal((2, (1,), 0)); Decimal((-1, (1,), 0)); Decimal(('0', (1,), 0)); Decimal((1.0, (1,), 0)) (float, not int); Decimal((True, (1,), 0)) actually passes because bool subclasses int and True == 1.
Common situations: Deserializing a decimal triple from JSON where the sign became a string or was computed as -1/other values; hand-building triples from sign math that yields -1 for negatives instead of 1.
Related errors
- Invalid tuple size in creation of Decimal from list or tuple
- The second value in the tuple must be composed of integers i
- The third value in the tuple must be an integer, or one of t
- argument must be a multiple of 32, with a maximum of {IEEE_C
- skip_file_prefixes must be a tuple of strs.
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/9127d3ba8c11212c.
Report an issue: GitHub.