dianping/cat · error · TypeError
Object.keys called on a non-object
Error message
Object.keys called on a non-object
What it means
es5-shim's Object.keys polyfill validates that its argument is an object or function and throws this TypeError otherwise. Note that unlike the native ES5 Object.keys (which coerces primitives and allows strings, returning index keys), the shim rejects ALL primitives including strings, so behavior can differ between shimming and native environments. null and undefined always throw in both.
Source
Thrown at cat-home/src/main/webapp/assets/js/editor/worker-xquery.js:49448
"valueOf",
"hasOwnProperty",
"isPrototypeOf",
"propertyIsEnumerable",
"constructor"
],
dontEnumsLength = dontEnums.length;
for (var key in {"toString": null}) {
hasDontEnumBug = false;
}
Object.keys = function keys(object) {
if (
(typeof object != "object" && typeof object != "function") ||
object === null
) {
throw new TypeError("Object.keys called on a non-object");
}
var keys = [];
for (var name in object) {
if (owns(object, name)) {
keys.push(name);
}
}
if (hasDontEnumBug) {
for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
var dontEnum = dontEnums[i];
if (owns(object, dontEnum)) {
keys.push(dontEnum);
}
}
}
return keys;View on GitHub (pinned to e815e74d4c)
Solutions
- Default the value before iterating: Object.keys(obj || {}).
- If strings can reach the call, convert explicitly: Object.keys(String(s).split('')) or gate on typeof first.
- Trace why the value is null/undefined — usually an upstream missing assignment or a failed lookup.
Example fix
// before
var keys = Object.keys(response.headers); // headers may be null
// after
var keys = Object.keys(response.headers || {}); Defensive patterns
Strategy: validation
Validate before calling
var keys = Object.keys(obj == null ? {} : (typeof obj === 'string' ? obj.split('') : obj)); Type guard
function isKeyable(v) {
return v !== null && v !== undefined && (typeof v === 'object' || typeof v === 'function' || typeof v === 'string');
} Prevention
- Default before iterating: Object.keys(x || {})
- Do not call Object.keys on strings if legacy engines must run the code
- Initialize object fields to {} instead of leaving them null
When it happens
Trigger: Object.keys(null), Object.keys(undefined) (e.g. iterating an optional field that was never set), Object.keys(42). Object.keys('abc') works natively (returns ['0','1','2']) but throws under this shim on old engines — a real portability trap.
Common situations: Iterating over a config object that a previous step failed to populate; API responses where a field is null instead of {}; code developed on a modern browser (where Object.keys('str') silently works) then executed in the worker on a legacy engine.
Related errors
- Object.defineProperty called on non-object: {object}
- can't convert {o} to object
- typeof prototype[{typeof prototype}] != 'object'
- Property description must be an object: {descriptor}
- {fun} is not a function
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/084bcb7953ec3950.
Report an issue: GitHub.