numpy/numpy · error · TypeError
{_block_format_index(parent_index)} is a tuple. Only lists c
Error message
{_block_format_index(parent_index)} is a tuple. Only lists can be used to arrange blocks, and np.block does not allow implicit conversion from tuple to ndarray. What it means
Raised by np.block's depth-checker when it encounters a tuple nested inside the block structure. np.block deliberately only accepts lists for arranging blocks and refuses to implicitly convert a tuple into an ndarray, because treating a tuple as data would be ambiguous.
Source
Thrown at numpy/_core/shape_base.py:592
-------
first_index : list of int
The full index of an element from the bottom of the nesting in
`arrays`. If any element at the bottom is an empty list, this will
refer to it, and the last index along the empty axis will be None.
max_arr_ndim : int
The maximum of the ndims of the arrays nested in `arrays`.
final_size: int
The number of elements in the final array. This is used the motivate
the choice of algorithm used using benchmarking wisdom.
"""
if isinstance(arrays, tuple):
# not strictly necessary, but saves us from:
# - more than one way to do things - no point treating tuples like
# lists
# - horribly confusing behaviour that results when tuples are
# treated like ndarray
raise TypeError(
f'{_block_format_index(parent_index)} is a tuple. '
'Only lists can be used to arrange blocks, and np.block does '
'not allow implicit conversion from tuple to ndarray.'
)
elif isinstance(arrays, list) and len(arrays) > 0:
idxs_ndims = (_block_check_depths_match(arr, parent_index + [i])
for i, arr in enumerate(arrays))
first_index, max_arr_ndim, final_size = next(idxs_ndims)
for index, ndim, size in idxs_ndims:
final_size += size
if ndim > max_arr_ndim:
max_arr_ndim = ndim
if len(index) != len(first_index):
raise ValueError(
"List depths are mismatched. First element was at "
f"depth {len(first_index)}, but there is an element at "
f"depth {len(index)} ({_block_format_index(index)})"View on GitHub (pinned to e117b3ca4e)
Solutions
- Replace any tuple grouping with a list: use [...] not (...) for block rows.
- Convert tuple inputs to lists: [list(t) for t in rows].
- If a tuple is meant to be a single array operand, wrap it with np.array(t) first.
Example fix
// before np.block([[a, b], (c, d)]) // after np.block([[a, b], [c, d]])
Defensive patterns
Strategy: type-guard
Validate before calling
def no_tuples(node):
if isinstance(node, tuple):
raise TypeError('np.block expects lists, not tuples')
if isinstance(node, list):
for x in node: no_tuples(x)
no_tuples(arrays) Type guard
def block_is_list_only(node):
if isinstance(node, tuple): return False
if isinstance(node, list):
return all(block_is_list_only(x) for x in node)
return True Prevention
- Use square brackets exclusively when building np.block layouts.
- Convert tuple rows to lists before passing: [list(r) for r in rows].
- Wrap any tuple meant as data with np.array().
When it happens
Trigger: Calling np.block([...]) where one of the nested elements is a tuple instead of a list or array, e.g. np.block([[a, b], (c, d)]).
Common situations: Using parentheses out of habit for grouping instead of brackets; a function returning a tuple that is fed directly into block; converting a list literal to a tuple inadvertently.
Related errors
- Can only multiply by integers
- For this input type lists must contain either int or Ellipsi
- Did not understand the path: {str(path_type)}
- Unknown input type
- arrays to stack must be passed as a "sequence" type such as
AI-assisted analysis of numpy/numpy@e117b3ca4e (2026-08-07).
Data as JSON: /api/errors/d9d4a695ed0bbd8f.
Report an issue: GitHub.