{"record":{"id":"18338fad70a70ce3","repo":"different-ai/openwork","slug":"object-keys-expects-a-data-object-or-array","errorCode":null,"errorMessage":"Object.keys expects a data object or array.","messagePattern":"Object\\.keys expects a data object or array\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/stdlib/object.ts","lineNumber":28,"sourceCode":"  const requireObject = (): Record<string, unknown> => {\n    const value = boundedData(args[0], `Object.${name} input`)\n    if (isSandboxValue(value)) return {}\n    if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n      throw new InterpreterRuntimeError(`Object.${name} expects a data object.`, node)\n    }\n    return value as Record<string, unknown>\n  }\n  const guardedSet = (out: Record<string, unknown>, key: string, item: unknown): void => {\n    if (isBlockedMember(key)) throw new InterpreterRuntimeError(`Property '${key}' is not available in CodeMode.`, node)\n    out[key] = item\n  }\n  switch (name) {\n    case \"keys\": {\n      const value = boundedData(args[0], \"Object.keys input\")\n      if (isSandboxValue(value)) return []\n      if (Array.isArray(value)) return Object.keys(value)\n      if (value === null || typeof value !== \"object\") {\n        throw new InterpreterRuntimeError(\"Object.keys expects a data object or array.\", node)\n      }\n      return Object.keys(value)\n    }\n    case \"values\":\n      return Object.values(requireObject())\n    case \"entries\":\n      return Object.entries(requireObject()).map(([key, item]) => [key, item])\n    case \"hasOwn\":\n      return Object.hasOwn(requireObject(), String(args[1]))\n    case \"assign\": {\n      const out: Record<string, unknown> = Object.create(null)\n      for (const source of args) {\n        if (source === null || source === undefined) continue\n        const value = boundedData(source, \"Object.assign input\")\n        if (isSandboxValue(value)) continue\n        if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n          throw new InterpreterRuntimeError(\"Object.assign expects data objects.\", node)\n        }","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/stdlib/object.ts#L10-L46","documentation":"The Object.keys branch of invokeObjectMethod accepts plain objects and arrays but throws for anything else (null, undefined, primitives, sandbox values). This is narrower than real JS, where Object.keys coerces primitives; CodeMode demands actual data containers.","triggerScenarios":"Object.keys(null), Object.keys(undefined), Object.keys('abc'), Object.keys(42), Object.keys(true) inside a CodeMode script — typically when the input comes from a JSON.parse or API call that returned a scalar or null.","commonSituations":"API responses that are null on empty/missing resources then passed straight to Object.keys; string-typed config values assumed to be objects; optional fields left undefined.","solutions":["Coerce to object first: Object.keys(response ?? {})","Guard with a check: if (value && typeof value === 'object') before calling Object.keys","For strings, use value.length / indexing instead of Object.keys","For primitives you truly want keys of, wrap: Object.keys(Object(value)) only if the sandbox allows — otherwise restructure"],"exampleFix":"// before\nconst names = Object.keys(config)\n// after\nconst names = Object.keys(config ?? {})","handlingStrategy":"type-guard","validationCode":"function assertKeysInput(v: unknown): asserts v is Record<string, unknown> | Array<unknown> {\n  if (v === null || (typeof v !== 'object')) throw new Error('Object.keys needs an object or array')\n}","typeGuard":"const isKeysInput = (v: unknown): v is object => v !== null && typeof v === 'object'","tryCatchPattern":"try {\n  return Object.keys(input)\n} catch (e) {\n  if (e instanceof InterpreterRuntimeError && e.message.includes('expects a data object or array')) {\n    return []\n  }\n  throw e\n}","preventionTips":["Default nullable inputs: Object.keys(x ?? {})","Check typeof before calling Object.keys","Handle scalar API responses upstream","Prefer explicit shape parsing over Object statics on unknown data"],"tags":["codemode","type-error","object","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}