I must have been dreaming about this - because I woke up and realized what you mean by the 'bug', i.e. the sprite being displayed in the tilemap. Let me try to explain what's happening. To improve performance - specifically batching to reduce draw calls - sprites, tilemap images etc. are combined into a spritesheet. Let's take a look at your project's spritesheet:
There you see your tilemap image and sprite together in the spritesheet. Your tilemap image has 64 individual tiles, with tile number 0 at the top through to tile number 63 at the bottom.
In the action Tilemap -> Set tile, the parameter 'Tile' is expecting a tile number, i.e. something between 0 and 62. But you are not giving it a tile number, you are giving it the Tilemap instance ID (self.IID). Each time you create your Tilemap object, it is creating an 'instance' of that object, and it is given an instance ID, the first Tilemap IID = 0, the second Tilemap IID = 1, the third Tilemap IID =3 and so on.
At the start of your layout you are creating 128 Tilemap instances, so Tilemap IID will range from 0 to 127. So what happens when you reach tile IID = 64 and use this as the Tile (number) parameter in the 'Set tile' action? There is no tile number 64 in your tilemap image, but Construct doesn't seem to check that, and keeps pulling data from the spritesheet, assuming there is another tile there. Eventually your Tilemap IID and hence Tile parameter is so that large that it reaches the Sprite image in your spritesheet, and starts putting that data into your Tilemap.
For those who are really interested and want to keep reading - would I call this a bug? Probably not. I would call it an 'unintended use case'. What's the difference? A bug is when your code is correct but the result is wrong. An unintended use case is when your code is wrong, but the engine still lets you do it anyway, and gives a strange result.
I have reproduced it in a minimal project and will report it anyway just so they are aware. It will be up to the Construct team if they decide to 'fix' it.
Because I think this might be interesting topic for some people - why might they decide NOT to fix an unintended use case?
Assuming my theory is correct, the problem could probably be fixed by 'bounds checking' the Tile parameter in the Set tile action. It would do something like:
if tile number > max tile number { tile number = max tile number}
This would stop it from moving out of the tilemap image into the rest of the spritesheet. They might decide to do a fix like this to stop people from making the same mistake.
But why might they NOT do a fix like this? Because it might have a negative performance impact on people who are using the Set tile action correctly. The bounds check adds an additional calculation that has to be done every time Set tile is used. For people who are for example, doing procedural generation on a tilemap, or using a chunk system to stream data into a tilemap for a large open world game, this could reduce their performance.