Skip to content

avoid runtime errors on iterating over non-array#5796

Merged
adhami3310 merged 3 commits intomainfrom
khaleel/eng-7615-never-foreach-over-a-non-iterable-value
Sep 17, 2025
Merged

avoid runtime errors on iterating over non-array#5796
adhami3310 merged 3 commits intomainfrom
khaleel/eng-7615-never-foreach-over-a-non-iterable-value

Conversation

@adhami3310
Copy link
Member

No description provided.

@linear
Copy link

linear bot commented Sep 16, 2025

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Summary

This PR addresses a critical runtime error in Reflex's foreach component by modifying the JavaScript code generation to handle non-iterable values safely. The change is in the render_iterable_tag method within reflex/compiler/templates.py, specifically on line 89.

The core issue was that Reflex's Foreach component generates JavaScript code that calls .map() directly on state variables. However, these state variables might be undefined, null, or other non-array values, which would cause a TypeError at runtime when JavaScript attempts to call .map() on them.

The solution uses Array.prototype.map.call() combined with the nullish coalescing operator (?? []) to ensure there's always a valid array-like structure to iterate over. This approach is defensive programming that prevents crashes while maintaining backward compatibility.

This change integrates well with Reflex's existing architecture where the Foreach component (located in reflex/components/core/foreach.py) is responsible for rendering iterables in the frontend. The compiler templates generate the actual JavaScript that gets executed in the browser, so this fix ensures that the generated code is robust against edge cases where state initialization or updates might result in non-iterable values.

Confidence score: 4/5

  • This PR is safe to merge with low risk as it implements defensive programming without breaking existing functionality
  • Score reflects a targeted fix for a specific runtime error with minimal code changes and good defensive programming practices
  • Pay close attention to reflex/compiler/templates.py to ensure the JavaScript generation logic is correct

1 file reviewed, no comments

Edit Code Review Bot Settings | Greptile

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 16, 2025

CodSpeed Performance Report

Merging #5796 will not alter performance

Comparing khaleel/eng-7615-never-foreach-over-a-non-iterable-value (1053753) with main (f226bb8)

Summary

✅ 8 untouched

Copy link
Collaborator

@masenf masenf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still a frontend error when iterating over an object that is null

class StateB(rx.State):
    @rx.var
    def bar(self) -> dict[str, str]:
        pass

app = rx.App()
app.add_page(lambda: rx.foreach(StateB.bar, lambda kv, ix: rx.heading(f"{kv[0]}: {kv[1]}")), route="/")
TypeError: Cannot convert undefined or null to object
    at Object.entries (<anonymous>)
    at Fragment_858197c9eca88a9a9f9ff055ea1c0363 (http://localhost:3001/app/routes/_index.jsx?import:10:60)

@adhami3310
Copy link
Member Author

that has less to do with iterating over an object and more of calling entries on a null

@masenf
Copy link
Collaborator

masenf commented Sep 17, 2025

the motivation for this change is to minimize the number of runtime errors that users (AI) accidentally write when dealing with state and foreach; so i think we should extend this to Object.entries at least in the case of rx.foreach, it shouldn't blow up if the value is null or undefined.

@adhami3310
Copy link
Member Author

i made it such that keys values and entries wouldn't throw a runtime error if any value gets passed to them

@adhami3310 adhami3310 merged commit 6d8b083 into main Sep 17, 2025
41 checks passed
@adhami3310 adhami3310 deleted the khaleel/eng-7615-never-foreach-over-a-non-iterable-value branch September 17, 2025 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants