Skip to main content

The error “No aggregated item, sequence was empty” comes from Jinja2

You get this error message if you try to use Jinja2’s filters to get the min/max of an empty sequence.

I was debugging a Python app recently, and I saw an error message in my logs that I didn’t recognise:

jinja2.exceptions.UndefinedError: No aggregated item, sequence was empty.

I didn’t recognise this error, and I couldn’t find anything about it in Google either. (The only search result for this error is a forum thread about home automation, which has the same issue which only hints at the issue.)

I did some debugging and I worked out where it came from – here are my notes.

What causes this error?

In my traceback, I could see this was coming from Jinja2’s min() and max() filters. If you try to get the min and max of an empty list, that causes the error:

import jinja2

t = jinja2.Template("{{ 1 + (my_list|max) }}")

print(t.render(my_list=[]))

Note that the 1 + is required to cause the error – you have to interact with the my_list|max value, otherwise it’s undefined and gets rendered as an empty string.

If I’d enabled StrictUndefined, the error would be thrown even if I just rendered the value in the template, and didn’t try to modify it. Here’s another example:

import jinja2

t = jinja2.Template("{{ my_list|max }}", undefined=jinja2.StrictUndefined)

print(t.render(my_list=[]))

The fix is to ensure you’re not trying to get the min() or max() of an empty list – if you’re not certain the input list will be non-empty, add a check beforehand.

Where does this error come from?

Once I knew this error came from Jinja2, I was able to search the Jinja2 codebase and find the function where this error is being returned:

def _min_or_max(
    environment: "Environment",
    value: "t.Iterable[V]",
    ...
) -> "t.Union[V, Undefined]":
    it = iter(value)

    try:
        first = next(it)
    except StopIteration:
        return environment.undefined("No aggregated item, sequence was empty.")

    ...
From filters.py, lines 486–498, in pallets/jinja

Until I saw this code, I didn’t realise Undefined was an actual type – I’ve only ever encountered it in the sense of “undefined variable”, which is a fairly common programming error, and not necessarily associated with a type.

Digging into this a little further, I discovered that there’s a class jinja2.Undefined, which is used in several places beyond “your template tried to use a variable that doesn’t exist”.

The documentation also explains why, when I wasn’t using StrictUndefined, I had to interact with the variable before I could throw an error (emphasis mine):

class jinja2.Undefined – The default undefined type. This can be printed, iterated, and treated as a boolean. Any other operation will raise an UndefinedError.

This is an interesting idea that I don’t think I’ve come across before. There are lots of languages that have an empty value like null or undefined, but I can’t recall seeing any where you can attach an error message that can be used for debugging. It feels similar to something like an Option or an Err type, but a value being undefined isn’t necessarily an error.