Skip to content

Fix Excel LET and LAMBDA #VALUE! Errors with Spilled Arrays

A user in the Microsoft Tech Community recently posted a common frustration: “I have a spilled range in A2#. I’m trying to use MAP to iterate through it and a LET function to perform some logic. However, as soon as my LET function references the spilled range A2# or tries to return an array, the whole cell just gives me a #VALUE! error. Why can’t Excel handle this?”

This issue typically stems from one of two things: referencing the “parent” spilled range inside a loop that is already iterating over it, or the “Array of Arrays” limitation.

Tested on: Microsoft 365 (Version 2408) and Excel for the Web.

In this scenario, the user is trying to find the rank of each number in a spilled range.

=MAP(A2#, LAMBDA(x, LET(full_range, A2#, MATCH(x, SORT(full_range), 0))))

Result: #VALUE!

To fix this, you must ensure the LET function isn’t trying to re-evaluate the spilled range in a way that creates nested array dependencies, or more commonly, ensure the result of the LAMBDA is a single value (scalar).

=LET(full_range, A2#, MAP(full_range, LAMBDA(x, MATCH(x, SORT(full_range), 0))))

Why It Works: The “Array of Arrays” Rule

Section titled “Why It Works: The “Array of Arrays” Rule”

Excel’s calculation engine currently has a limitation: It cannot handle an array that contains other arrays.

When you use a helper function like MAP, SCAN, or BYROW, Excel expects the LAMBDA to return a single value for every iteration. If your LET block performs a calculation that results in even a small array (e.g., a 1x1 array), the formula will fail with a #VALUE! error.

Component Role in Formula The #VALUE! Trap
MAP Iterates through each item in a range. Expects the inner function to return a scalar (single value).
LAMBDA The “engine” defining the logic. Cannot return an array to the MAP function.
LET Defines variables for efficiency. Referencing a spilled range (#) inside the loop can cause dimension conflicts.
A2# The spilled array reference. Best defined outside the MAP function to avoid recalculating the range for every row.

If you are seeing the #VALUE! error while using LET and LAMBDA, follow these steps to debug:

  1. Move Range Definitions Outside: Instead of putting LET(rng, A2#, ...) inside the LAMBDA, wrap the entire MAP function inside the LET. This defines the range once and makes it available to the loop without re-triggering the dynamic array engine.
  2. Force a Scalar Result: If your LET calculation returns an array but you only need one value, wrap your result in INDEX(result, 1) or SUM(result) to ensure it isn’t passing an array back to the MAP function.
  3. Check for Implicit Intersection: If you reference A2 (without the #) inside a MAP iterating over A2#, Excel might get confused about which row it should look at. Always use the variable defined in your LAMBDA (e.g., the x in LAMBDA(x, ...)).

What if I actually need to return multiple columns? If your goal is to have MAP return more than one column per row (which usually causes the #VALUE! error), MAP is the wrong tool. Instead, use the REDUCE function combined with VSTACK or HSTACK. This allows you to build a complex array piece by piece.

Can I use this with filtered data? Yes. If A2# is the result of a FILTER function, the logic remains the same. However, ensure that your LET variables are referencing the spilled range name, not the hardcoded coordinates, to keep the formula dynamic.

Why does LET work fine on its own but fail inside MAP? Inside a MAP or BYROW function, Excel enters a “row-by-row” context. LET functions inside that context are subject to stricter memory and dimensionality rules. By defining your variables at the very beginning of the formula (the outermost level), you avoid the overhead of re-declaring those arrays for every single iteration of the loop.