< Back to Blog

The xarray Truthiness Bug That Crashed My Weather Bot Silently

TL;DR / Key Takeaways

  • Using Python's or operator on an xarray DataArray raises ValueError: The truth value of an array is ambiguous because xarray refuses to reduce a multi-element array to a single boolean.
  • This error does not always blow up loudly. In certain exception-handling paths it gets swallowed and the function returns None, which looks like missing data rather than a crash.
  • The fix is explicit None checks, never truthiness tests, when working with xarray objects that may or may not exist.
  • The Predict & Profit Weather Bot v2.1 has this patched in the AIGEFS module. If you are running an older copy, check your coordinate extraction code.

I spent two hours thinking the NOAA AIGEFS data was corrupted.

It was not corrupted. My coordinate extraction was crashing on every file and returning None so quietly that the bot just skipped AIGEFS entirely, logged nothing useful, and kept running on three sources instead of four. No exception in the main thread. No alert. Just silently wrong.

This is the kind of bug that makes you question everything you know about your own code.

What I Was Trying to Do

The AIGEFS module pulls GRIB2 files from NOAA's public AWS S3 bucket and opens them with cfgrib via xarray.open_dataset(). After opening, I needed to extract the latitude and longitude coordinate arrays to find the grid point closest to the target city.

The code looked roughly like this:

def get_coordinates(ds):
    lat = ds.get("latitude") or ds.coords.get("latitude")
    lon = ds.get("longitude") or ds.coords.get("longitude")
    return lat, lon

Reasonable looking. Works fine in pandas. Works fine with plain numpy arrays. Completely explodes with xarray.

Why It Fails

When ds.get("latitude") finds a coordinate, it returns an xarray.DataArray. Python then evaluates xarray_dataarray or fallback which requires reducing that DataArray to a single boolean.

xarray refuses to do that. If the array has more than one element, it cannot decide if the whole thing is "truthy" or not. So it raises:

ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()

numpy does the same thing. You have probably hit this before with numpy and immediately knew what it was. With xarray it can be less obvious because the stack trace goes through cfgrib internals before surfacing.

The specific problem in my case is that the coordinate arrays have hundreds of elements. One per grid point across the forecast domain. Of course they are ambiguous. Python has no idea what you meant.

Why It Failed Silently

Here is the part that cost me two hours.

The get_coordinates() call was inside a broader try/except Exception block in the AIGEFS loader. The ValueError fired, the except caught it, logged a generic "AIGEFS coordinate extraction failed" warning at DEBUG level (not WARNING, not ERROR, DEBUG), and returned None, None.

The caller then checked if lat is None and skipped the file.

868 files. 868 silent skips. The bot ran without AIGEFS the entire time and I had no idea because the top-level log showed "AIGEFS: 0 members loaded" which I had not yet learned to read as a red flag.

Zero trades were affected because this was during dry-run integration testing. But it would have been a real problem in production. The grand ensemble would have been running at 75% capacity and I would have had no idea.

The Fix

Replace truthiness tests with explicit None checks.

def get_coordinates(ds):
    lat = ds.get("latitude")
    if lat is None:
        lat = ds.coords.get("latitude")

    lon = ds.get("longitude")
    if lon is None:
        lon = ds.coords.get("longitude")

    return lat, lon

That is it. Two or operators replaced with four lines. The ValueError disappears because we never ask Python to evaluate the DataArray as a boolean. We only check whether the result of .get() is the Python object None.

If you need element-wise logic on the array itself later, use .notnull(), .any(), .all(), or numpy comparisons. Never or, never and, never not on a DataArray directly.

The Broader Pattern

This bug belongs to a class I think of as "works on scalars, explodes on arrays." It shows up constantly when you port logic from a context where variables are simple Python objects into a context where they might be array-like.

The dangerous version is when you have a convenience wrapper that catches broad exceptions. The ValueError gets absorbed, the function degrades gracefully to None, and the caller interprets None as "data not available" rather than "something crashed." The system keeps running. The results are wrong. You find out much later, maybe never.

A few rules I now follow in data pipeline code:

Never use or for fallback logic when the left side might be a numpy array, an xarray DataArray, a pandas Series, or a DataFrame. Use explicit is None checks.

Never catch Exception broadly in a data loading function without at minimum logging at WARNING or above with the full traceback. DEBUG level swallows too much.

If a data source returns zero members when you expected hundreds, treat that as an error condition immediately. Zero is not a valid ensemble size.

What v2.1 Ships With

The patched get_coordinates() function is in the AIGEFS module in Weather Bot v2.1. The broader fix also tightened the exception logging so any future coordinate failures come out at WARNING level with the file path and exception message. Silent failures are harder to hide now.

If you bought the bot before the v2.1 release, check your AIGEFS loader for any or operators applied to ds.get() results. One line change, but it matters.

This was not the most complex bug I have fixed. It was one of the most annoying to find, specifically because the code looked correct. Python's truthiness model is intuitive until you leave the world of scalars, and then it will absolutely wreck you if you are not paying attention.


title: "The xarray Truthiness Bug That Crashed My Weather Bot Silently" date: "2026-05-28" excerpt: "How Python's or operator on an xarray DataArray raises a silent ValueError that took down my AIGEFS integration before it ever ran a real trade." tags:

  • Python
  • Debugging
  • xarray
  • Weather Bot
  • Data Engineering