Q:

Why doesn't this Less compile? What can I do to fix it?

As this is, it complains that:

SyntaxError: error evaluating function darken: a.toHSL is not a function on line 24, column 1:

It seems like this should work; what am I doing wrong? How can I get the effect that I want?
@red2: #842211;
@green2: #842212;
@blue2: #842213;

@colors: red2, blue2, green2;

.color-style-helpers(@colors; @index) when (@index > 0) {
  .color-style-helpers(@colors; (@index - 1));

  @colorName : extract(@colors, @index);
  @color : ~"@{@{colorName}}";
  // @color : #ffffff; // Uncomment this line and this will work
  @darkColor : darken(@color, 10%);      

  .background-@{colorName} {    
    border-color: @darkColor;
    background-color: @color;
  }     
}

.color-style-helpers(@colors; length(@colors););

You can see the results here

A:

The problem is with the below line of code in your example. It makes the content of the @color var be treated as a string instead of a color. Because of this, the Less compiler couldn't convert the color to its HSL value which is required for the darken function and thus results in the error.
@color : ~"@{@{colorName}}";

Instead of that, just use the double @ syntax. There is no need for the wrapping quotes or the escape function for your case.
@color : @@colorName;

