A webkit bug that shipped in iOS 8 beta 5 and appears to have been partially included in the launch of iOS 8 and 8.1 is affecting many of our customers. It does not seem to impact all iOS8 uniformly; different versions of webkit seem to be involved.

The Error

The error will be recorded as:

TypeError: Attempted to assign to readonly property.

What’s Actually Happening

This is a pretty nasty bug in the WebKit JavaScript engine’s JIT compiler. When your code uses Object.create() and runs in strict mode, the compiler gets confused during optimization and tries to assign properties to the prototype instead of the actual object. Since prototype properties are often readonly, boom—you get this error.

The bug is reported in WebKit as WebIDL attributes should be implemented as getters and setters on the prototype object and the specific iOS 8 issue as WebKit bug #138038. It only affects 32-bit ARM devices (iPhone 4S, 5, 5C, iPad 2, etc.) because the 64-bit processors use different optimization paths.

Frameworks Hit Hard

This bug wreaked havoc on popular JavaScript frameworks:

Ember.js apps would show white screens when rendering nested {{#each}} loops. The framework’s mixin system relies heavily on prototype manipulation, which triggered the bug during template compilation. Check Ember issue #5606 for the gory details.

Angular 1.2.25 had problems with scope creation in rootScope.js. Multiple property assignments like this.$$watchers = this.$$nextSibling = null would fail on iOS 8. See Angular issue #9128.

Polymer apps crashed during startup because the Web Components polyfills tried to assign properties that the buggy JIT marked as readonly.

Solutions That Actually Work

Each framework encountered this differently, but here are the main workarounds:

Remove Strict Mode (Quick but Dirty)

The fastest fix is removing "use strict" declarations from your code. In non-strict mode, the failed assignments just fail silently instead of throwing errors. Not ideal, but it works.

Framework Updates

  • Ember: Upgrade to versions with iOS 8 compatibility patches, or use the yapplabs/ember-ios8-fix build
  • Angular: Upgrade to 1.3+ or use angular.copy() for deep object copying
  • Polymer: Update to newer polyfill versions that include workarounds

Alternative Object Creation

Avoid Object.create() entirely by using constructor patterns:

// Instead of Object.create()
function SafeConstructor() {}
SafeConstructor.prototype = myPrototype;
var obj = new SafeConstructor();

Property Assignment Fallbacks

For bulletproof code, wrap property assignments in try-catch blocks:

try {
    obj.property = value;
} catch(e) {
    if (e.message.includes('readonly')) {
        // Fallback assignment method
        Object.defineProperty(obj, 'property', {
            value: value,
            writable: true
        });
    }
}

The Resolution

Apple fixed this in iOS 9 but never backported the fix to iOS 8. The bug was finally resolved in WebKit changeset r184960 in May 2015, but developers had to maintain workarounds until iOS 8 usage dropped significantly.

If you’re still seeing this error, check your framework version and consider the workarounds above. The good news is that this specific bug is mostly historical now, but understanding it helps when debugging similar JIT-related issues in other browsers.

TrackJS is the easy way to monitor your JavaScript applications and fix production errors. TrackJS is provides detailed error monitoring and alerting to developers around the world at companies like 3M, Tidal, IKEA, Venmo, Allbirds, and Frontend Masters. TrackJS catches millions of errors from users everyday. Let's start catching yours.

Protect your JavaScript