A few years ago, I wrote about a spread operator bug in Adobe ColdFusion 2023 that creates phantom struct key. The tracker ticket for that issue — CF-4222643 — was marked fixed in 2024. But, I just ran into a variation on it in the latest Adobe ColdFusion 2025. They fixed the spreading of static collections into a new struct; but, they did not fix the spreading of dynamic collections into a new struct.
Here's a demonstration of the variation they fixed alongside the variation that's still buggy:
<cfscript>
// Static collection of values.
values = [
v1: "a",
v2: "b",
];
// Dynamic collection of values.
valuesGenerator = () => [
v1: "a",
v2: "b",
];
// Spreading static collection bug was FIXED! (Ticket: CF-4222643)
writeDump({ ...variables.values });
// Spreading dynamic collection bug is NOT FIXEX!
writeDump({ ...variables.valuesGenerator() });
</cfscript>
As you can see, all we're doing is spreading a scoped value into a new struct. The only difference between the last two lines is whether the value that we're spreading is a reference to a static collection or a dynamic collection (ie, one resulting from a method call).
If we run this in Adobe ColdFusion 2025 update 13, we get the following output:
As you can see, when spreading variables.values into a new object, the values keys are properly copied. However, when spreading variables.valuesGenerator() into a new object, ColdFusion incorrectly creates a variables key in the resultant struct.
Today, you work around this by storing the .valuesGenerator() result into an intermediary variable; and then spreading said intermediary variable into the next object. But I will open a new ticket in the tracker for this.
Reader Comments
I filed a ticket in the Adobe Tracker:
CF-4234744 - Spread operator adds phantom struct key when spreading result of scoped method call.
Good catch, and the intermediary-variable workaround is the kind of thing I'd never have guessed. I run the same code on Adobe ColdFusion and Lucee, and I keep finding spots like this where one engine quietly does something different with an expression the other handles fine. My last one was an HQL map projection that only threw on one engine. These small, focused write-ups make those so much faster to recognize. Thanks!
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →