dianping/cat · error · TypeError

Property description must be an object

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.

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.

Appendix: 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)