polyfill-library: Invalid descriptor for property '0'

In IE 11, I’m getting the error:

Invalid descriptor for property ‘0’

Walking up the call stack, it’s stemming from some code that is constructing a DOMTokenList with a body element and 'className':

e=new DOMTokenList(body, 'className');

…which eventually hits this code which throws the error:

_(y,n,r)
  • _ is some function named defineProperty
  • y is some object
  • n is 0
  • r is set to undefined

I’m using this polyfill URL (linebreaks added for readability):

https://cdn.polyfill.io/v2/polyfill.min.js
  ?unknown=polyfill
  &features=
    default%2C
    fetch%2C
    Array.prototype.%40%40iterator%2C
    Array.prototype.find%2C
    Array.prototype.findIndex%2C
    Function.name%2C
    Number.isFinite%2C
    Promise%2C
    String.prototype.repeat%2C
    Array.prototype.includes%2C
    Intl.~locale.en-US%2C
    Promise.prototype.finally

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 10
  • Comments: 21 (5 by maintainers)

Most upvoted comments

With this code is possible to simulate on IE11 or also Chrome 37 (Before Symbol support) since it is easier to debug on Chrome:

delete Object.prototype[Symbol.toStringTag] // At some point the prototype key is being deleted

try {
  var a = {}
  Object.defineProperty(a, Symbol.toStringTag, { value: 42 })
} catch (error) {
  console.log('Ops error', error);  // "Property description must be an object: undefined"
}

console.log(a[Symbol.toStringTag]) // 42
console.log(a.propertyIsEnumerable(Symbol.toStringTag))
// Cannot read property '@@__symbol:toStringTag0.85429089097306135' of undefined 

At some point the key Symbol.toStringTag in the Object.prototype is being deleted. I am having this issue using Webpack + ReactUniversalComponent in dev mode.

Here’s the unminified stacktrace:

TypeError: Invalid descriptor for property '0'
   at setDescriptor (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:1812:4)
   at defineProp (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:1715:4)
   at defineGetter (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:2609:4)
   at addIndexGetter (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:2633:4)
   at reindex (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:2644:6)
   at preop (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:2681:4)
   at _DOMTokenList (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:2685:3)
   at Anonymous function (https://cdn.polyfill.io/v2/polyfill.js?features=default,es6,es7,es2017,fetch,IntersectionObserver:3022:11)

That setDescriptor function is from the Symbol polyfill:

	setDescriptor = function (o, key, descriptor) {
		var protoDescriptor = gOPD(ObjectProto, key); // gOPD = The original Object.getOwnPropertyDescriptor, before being wrapped by this polyfill
		delete ObjectProto[key];
		defineProperty(o, key, descriptor);  // This line succeeds with args: o = _DOMTokenList, key = '0', descriptor = {configurable: false}
		if (o !== ObjectProto) {
			defineProperty(ObjectProto, key, protoDescriptor); // This line throws the exception with args: ObjectProto = Object.prototype, key = '0', protoDescriptor = undefined
		}
	};

If I try the same call in Firefox (Object.defineProperty(Object.prototype, '0', undefined)) I get the error TypeError: descriptor must be an object, got undefined, so this probably isn’t exclusively an IE11 bug, it probably occurs in IE11 because IE is the only major browser that gets the DOMTokenList polyfill.

Using in combination with Next.js, also bumping on this issue. Any real workaround?

@JakeChampion Also seeing this. I’m on polyfill-library@3.33.0. I am unable to create a repro on jsbin because repro involves a giant IE11 polyfill file. However, I am generating that file like this:

const ie11_es6_opts = {
  uaString: 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
  minify: false,
  features: {
    'es6': { flags: ['gated'] }
  }
};

const devStream = fs.createWriteStream('polyfill-ie11-es6.js');
polyfillLibrary.getPolyfillString(ie11_es6_opts).then(bundleString => {
  devStream.write(bundleString);
  devStream.close();
});

Include that file in a barebones HTML file:

<html>
    <head>
        <title>Invalid descriptor repro</title>
        <script src="polyfill-ie11-es6.js"></script>
    </head>
    <body>
        Evaluate `Object.assign` in the console
    </body>
</html>

Open the console in IE11, and evaluate Object.assign (without even invoking it) yielding the error:

image

Stack:

setDescriptor [Line: 3683, Col: 4], polyfill-ie11-es6.js
defineProp [Line: 3586, Col: 4], polyfill-ie11-es6.js
Function$name [Line: 2306, Col: 5], polyfill-ie11-es6.js

Frame: image

I was able to replicate this when using both core-js (through babel preset-env) and polyfill.io.

Excluding web.dom-collections.iterator and web.dom-collections.for-each in your babel config might help. example

But core-js and polyfill.io have other conflicts so you will likely get other errors even if you exclude those.

Does the error happen simply by loading the polyfills on a blank page or is there surrounding code? If there is extra code, can you share the url where this happens?

In scrutinizing further, it seems clear that it’s in the defining of indexer properties where this problem is occurring:

https://github.com/Financial-Times/polyfill-service/blob/1f45e5b95625180117d5b2f1979d8e217bc791a4/packages/polyfill-library/polyfills/_DOMTokenList/polyfill.js#L35-L41