Why was my app rejected for Guideline 2.5.2?
19 Jul 2026 · 3 min read · Erik van Kammen
Guideline 2.5.2 covers code that can change your app's behaviour after review, like downloaded scripts or an embedded interpreter bridged to native APIs. Apple's concern is simple: an app that can rewrite itself after approval makes the review meaningless.
The frustrating part is that most teams who get this rejection did not set out to break the rule. A feature flag system grew into a config that ships expressions. A cross-platform framework bundled an interpreter. An SDK added a dynamic update mechanism nobody read the changelog for.
This is the nuance most rejection stories miss. Apple's rules explicitly permit code that is downloaded and run by the built-in WebKit or JavaScriptCore engines, as long as it does not change the app's primary purpose. That is why React Native apps pass review, and why over-the-air JavaScript updates through tools like CodePush or EAS Update are widely used without trouble.
The line is not whether a bridge to native code exists. It is whether downloaded code can introduce behaviour the reviewer never saw. Scripts that ship inside the binary go through review with everything else; it is the download that changes the question. And because iOS refuses writable and executable memory to third-party apps, even permitted interpreters run without JIT, which is why this whole class of behaviour can be judged from the binary.
A feature flag returning a boolean is data. A config returning an expression your app evaluates is code, and that crosses into 2.5.2 territory. Turning a feature off does not fix the rejection; the reviewer's objection is the capability, not the feature.
Identify the suspected code path. Then either bundle the logic into the binary so it ships through review, or move execution server-side so the app only receives results. In your response to App Review, name the code path and the change explicitly; vague appeals reliably fail.
Every one of these patterns is detectable in the binary before you submit. Our scan flags custom interpreters and dynamic execution paths that fall outside Apple's own engines, with the evidence, so you can restructure before the reviewer finds it.
Dynamic code is one class of technical rejection. Missing Required Reason API declarations are another.
Everything technical in this post is checkable from the build itself, and that is exactly what AppCompliance does: upload an iOS or Android build, and minutes later you have every issue that would get it rejected, with the exact fix next to it.
One email when we open the doors. No spam, just the launch.