Key already exist in (empty) struct


i have this method in a component “media” (it deals with media gallery on front-end websites):

any function resetAllMediaFormats()
		variables.media_formats = {};
		var s_listeFormats = "4";
		var nbFormat = listLen(s_listeFormats);
		for (var i=1; i lte nbFormat; i++) { 
			var id_format = listGetAt(s_listeFormats, i);
			variables.media_formats.insert(id_format, new media_format(this, id_format)); 
		return this;

It’s a method to initialize information about media formats (thumbnail, large view…)
here i just simplified code with only one format (ID=4).
It’s a real case. It works well when i browse the site, but regularly a receive this exception (by mail, with an error management mechanism):

key [4] already exist in struct

Thrown by the insert operation.
I really don’t understand how that can happen, with one item loop!
(i also tried another syntax: for (idFormat in s_listeFormats)… with same errors)

An idea ?

it’s a race condition, is there a component per request or is it persisted

looks like two requests are overlapping (i.e. use var not variables)

In that case, ONE temp media component is instanciated in a request and used in a loop (with a read operation for each media to show in the gallery, and then one call to method resetAllMediaFormats before reading, but it remains sequential in the request).

For me, using in a cfc a scope “variable” is a like a “deprecated” way, but globally the same thing that using a property (and needs explicit getter/setter).
I’m wrong ?

Anyway, my struct media_format can’t be local to this method.

I think that is exactly the issue. In that very same function you are resettingAllMediaFormat and initializing the variable.media_format to an empty struct. If you can’t use local scope, then you are probably doing something with lexical scoping (where you have redefined or are using that same variable outside your resetAllMediaFormat() function). Thus, I bet its a race condition as @Zackster said.

The context of these errors is uncertain. I have never encountered them while browsing the relevant pages. I just know the “user agent” triggers in my logs:

User agent : Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Mobile Safari/537.36 / Remote : / Referer :
User agent : Chrome Privacy Preserving Prefetch Proxy / Remote :…

But whatever the context, during one request, one object (here a “media”) works with multiples calls on its methods.
All are basic operations (init, read DB, display…, no threads).
Then, all are sequentials, how a race condition could happen ???

A couple of thoughts…

Is the same function or variable used in a schedule task?
Is it used in an email?
Is it used to set a “status” of some sort, that can change?
Is it used in an Application.cfc lifecycle method?


I still cannot understand… What happens if you set it to be local?

I applied a change in my cfc:
No more variables.media_formats but a property of type struct MediaFormats instead.
And in the method resetAllMediaFormats, something like:

var tempStruct = ....(working on tempStruct)...

I did not received any more error since this change was applied, some days ago.
An “implicit” solution ?

the potential for a race condition is eliminated when working on a local variable

I’ll remember it. Thank you for your advices.