{"record":{"id":"adac552356dded2a","repo":"antonmedv/fx","slug":"cannot-get-keys-of-typeof-x","errorCode":null,"errorMessage":"Cannot get keys of ${typeof x}","messagePattern":"Cannot get keys of (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"internal/engine/stdlib.js","lineNumber":151,"sourceCode":"  for (let i = 0; i < length; i++) {\n    res.push(x.map(a => a[i]))\n  }\n  return res\n}\n\nfunction flatten(x) {\n  if (Array.isArray(x)) return x.flat()\n  throw new Error(`Cannot flatten ${typeof x}`)\n}\n\nfunction reverse(x) {\n  if (Array.isArray(x)) return x.reverse()\n  throw new Error(`Cannot reverse ${typeof x}`)\n}\n\nfunction keys(x) {\n  if (typeof x === 'object' && x !== null) return Object.keys(x)\n  throw new Error(`Cannot get keys of ${typeof x}`)\n}\n\nfunction values(x) {\n  if (typeof x === 'object' && x !== null) return Object.values(x)\n  throw new Error(`Cannot get values of ${typeof x}`)\n}\n\nfunction list(x) {\n  if (Array.isArray(x)) {\n    for (const y of x) console.log(y)\n    return skip\n  }\n  throw new Error(`Cannot list ${typeof x}`)\n}\n\nfunction del(key) {\n  return function (x) {\n    if (Array.isArray(x)) {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/antonmedv/fx/blob/4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe/internal/engine/stdlib.js#L133-L169","documentation":"keys(x) returns Object.keys and accepts any non-null object — arrays count as objects, so keys([10,20]) returns ['0','1']. It throws 'Cannot get keys of <type>' for primitives (string, number, boolean, undefined) and for null. The null rejection is the common surprise: a missing/failed lookup yields null and this throws.","triggerScenarios":"keys(null), keys('abc'), keys(42), keys(undefined), keys(true) — null is the most frequent since JSON lookups commonly return null for absent data.","commonSituations":"Accessing a config/env object that failed to load (null), API responses with a missing payload, or accidentally passing a string when an object was intended.","solutions":["Coerce null to an empty object: keys(x ?? {})","Check x != null before calling keys","If x may be a string and you want its characters, split first: x.split('')","Wrap in try/catch when the input type is uncertain"],"exampleFix":"// before\nconst ks = keys(cfg.network)\n// after\nconst ks = keys(cfg?.network ?? {})","handlingStrategy":"fallback","validationCode":"if (x == null || typeof x !== 'object') throw new TypeError('keys() requires a non-null object; got ' + (x === null ? 'null' : typeof x))","typeGuard":"function isKeyed(x) { return x !== null && typeof x === 'object' }","tryCatchPattern":"let ks; try { ks = keys(x) } catch (e) { if (e.message.startsWith('Cannot get keys of')) { ks = [] } else { throw e } }","preventionTips":["Always default lookups: keys(x ?? {})","Treat null as 'no data' explicitly instead of passing it on","Check API/config responses for null payloads before object operations","Use optional chaining upstream: keys(cfg?.net ?? {})"],"tags":["type-error","null","runtime","stdlib"],"backgroundTag":"null-or-undefined-input","analyzedSha":"4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe","analyzedAt":"2026-09-02T02:17:47.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}