Skip to content

ValueError: If using all scalar values, you must pass an index

Have you tried to build a small data frame from a dictionary and been asked for an index?

pd.DataFrame({'a': 1, 'b': 2})
ValueError: If using all scalar values, you must pass an index

The dictionary is fine. The problem is that Pandas cannot tell how many rows you want. Given {'a': [1, 2, 3]} it makes three rows, because the list says so. Given {'a': 1} there is nothing to count, so it asks.

Three ways to answer, all equivalent in result:

pd.DataFrame({'a': 1, 'b': 2}, index=[0])
   a  b
0  1  2

Wrapping each value in a list says the same thing:

pd.DataFrame({'a': [1], 'b': [2]})
   a  b
0  1  2

And a list containing the dictionary reads best to me, because it says "here is one record" rather than "here is a column of length one":

pd.DataFrame([{'a': 1, 'b': 2}])

Which one to choose

For a genuine one-row frame, the list-of-dictionaries form scales without rewriting. Add a second record and nothing else changes:

pd.DataFrame([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}])

The index=[0] form is the one to reach for when the row needs a meaningful label rather than a position — index=['2026-01'], say.

Where this bites in real code

Rarely when typing a literal, and often when building a frame from something computed. A summary dictionary assembled in a loop, a row pulled from an API response, a set of totals — all of them end up as scalars, and all of them hit this.

If you are collecting rows to combine later, gather the dictionaries in a list and build the frame once at the end:

rows = []
for name in files:
    rows.append({'file': name, 'size': size_of(name)})

pd.DataFrame(rows)

That is both faster and clearer than concatenating a new frame on every pass, and it never meets this error, because a list of dictionaries carries its own row count.

The mistakes I see most often

Adding index=[0] to a dictionary that has lists in it. If any value is a list, you did not need the index, and forcing one to [0] will raise a length error instead.

Passing a Series where a dict was meant. pd.DataFrame(some_series) makes a one-column frame, not a one-row frame. If you want the row, some_series.to_frame().T transposes it.

Reaching for from_dict first. It has an orient='index' mode that solves a related problem, but for a single record the list-of-dictionaries form needs no argument at all.

Practice

See DataFrame in Pandas for the ways to build one, and concat in Pandas for combining rows you gathered separately.