dianping/cat · error · TypeError

Property description must be an object: {descriptor}

Error message

Property description must be an object: {descriptor}

What it means

es5-shim's Object.defineProperty fallback validates the third argument (the property descriptor) and throws this TypeError when it is not an object. A descriptor must be an object like {value: x}, {get: fn}, or {set: fn}; primitives, null, and undefined are rejected per the ES5 spec. The shim appends the offending value to the message, which helps identify what was actually passed.

Source

Thrown at cat-home/src/main/webapp/assets/js/editor/worker-xquery.js:49331

    var definePropertyWorksOnObject = doesDefinePropertyWork({});
    var definePropertyWorksOnDom = typeof document == "undefined" ||
        doesDefinePropertyWork(document.createElement("div"));
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
        var definePropertyFallback = Object.defineProperty;
    }
}

if (!Object.defineProperty || definePropertyFallback) {
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
                                      "on this javascript engine";

    Object.defineProperty = function defineProperty(object, property, descriptor) {
        if ((typeof object != "object" && typeof object != "function") || object === null)
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
        if (definePropertyFallback) {
            try {
                return definePropertyFallback.call(Object, object, property, descriptor);
            } catch (exception) {
            }
        }
        if (owns(descriptor, "value")) {

            if (supportsAccessors && (lookupGetter(object, property) ||
                                      lookupSetter(object, property)))
            {
                var prototype = object.__proto__;
                object.__proto__ = prototypeOfObject;
                delete object[property];
                object[property] = descriptor.value;
                object.__proto__ = prototype;
            } else {
                object[property] = descriptor.value;

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Wrap the intended value in a descriptor object: {value: v, writable: true, enumerable: true, configurable: true}.
  2. If the descriptor is computed, ensure every code path returns an object; add a default of {} or throw explicitly with context.
  3. If the descriptor may be absent, guard: only call defineProperty when descriptor != null.

Example fix

// before
Object.defineProperty(obj, 'count', 0); // wrong: raw value as descriptor

// after
Object.defineProperty(obj, 'count', { value: 0, writable: true, enumerable: true, configurable: true });
Defensive patterns

Strategy: validation

Validate before calling

if (descriptor === null || (typeof descriptor !== 'object' && typeof descriptor !== 'function')) {
  descriptor = { value: descriptor }; // or throw with context
}
Object.defineProperty(obj, prop, descriptor);

Type guard

function isPropertyDescriptor(d) {
  return d !== null && d !== undefined &&
    (typeof d === 'object' || typeof d === 'function');
}

Prevention

When it happens

Trigger: Object.defineProperty(obj, 'p', null); Object.defineProperty(obj, 'p', 'value'); Object.defineProperty(obj, 'p', undefined); or building a descriptor conditionally where a branch forgets to return an object (returns undefined).

Common situations: A descriptor factory function with a missing return on one path; passing a value directly instead of wrapping it ({value: v} is required, not v); JSON round-tripping a descriptor into a string; copy-paste from code that used assignment instead of defineProperty.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/360fa6d0b448e113. Report an issue: GitHub.