Skip to content

fix(table): don't crash on --query lists mixing scalars and objects - #10528

Open
devteamaegis wants to merge 1 commit into
aws:developfrom
devteamaegis:fix/table-output-mixed-query-list
Open

fix(table): don't crash on --query lists mixing scalars and objects#10528
devteamaegis wants to merge 1 commit into
aws:developfrom
devteamaegis:fix/table-output-mixed-query-list

Conversation

@devteamaegis

Copy link
Copy Markdown

What's broken

--output table exits 255 on a --query multi-select list that mixes a scalar with an object. --output json handles the same data fine.

$ aws ec2 describe-instances --output table \
    --query '[Reservations[0].Instances[0].InstanceId, Reservations[0].Instances[0].State]'
ValueError: Row should have 1 elements, instead it has 2

When the column counts happen to line up it's quieter but worse — the object's keys are printed as a data row and the values are dropped:

$ aws ... --output table --query '[[a, b], State]'
+----+-----+
|  a |  b  |
| Code | Name |     <- the 16 / "running" values are gone
+----+-----+

Why it happens

_build_table decided how to treat a list from current[0] alone. If element 0 isn't a dict, every element falls to the row branch — and a dict passes all(self._scalar_type(el) for el in item) there, because that iterates the dict's keys. It's then added as a row of keys, which either loses the values or trips Section.add_row's column-count check.

The fix

Route on whether every element is a dict rather than just the first, and give a dict inside a mixed list a section of its own (the same thing _build_sub_table_from_list already does per element). Homogeneous lists of dicts and lists of lists take exactly the path they did before.

|  i-123            |
+-------------------+
|   OperationName   |
+-------+-----------+
| Code  |   Name    |
+-------+-----------+
|  16   |  running  |

The test

test_mixed_list_with_leading_scalar and test_mixed_list_with_leading_dict in tests/unit/output/test_table_formatter.py. Both fail on develop and pass with the fix:

$ python -m pytest tests/unit/output/test_table_formatter.py -k mixed_list   # before
E   ValueError: Row should have 1 elements, instead it has 2
2 failed, 9 deselected

$ python -m pytest tests/unit                                                # after
2876 passed, 1 skipped

_build_table decided how to treat a list by looking at current[0] only.
When element 0 wasn't a dict, every element fell through to the row
branch, where a dict satisfies all(self._scalar_type(el) for el in item)
because that iterates the dict's keys.  It was then added as a row of
keys - dropping the values outright when the column counts happened to
match, and raising ValueError when they didn't.

A --query multi-select list such as '[InstanceId, State]' returns a
scalar next to an object, so --output table exited 255.

Route on whether every element is a dict, and give a dict in a mixed
list a section of its own.
@devteamaegis
devteamaegis marked this pull request as ready for review August 3, 2026 16:45
@devteamaegis
devteamaegis requested a review from a team as a code owner August 3, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant