{"record":{"id":"6f312a7e593b0c67","repo":"different-ai/openwork","slug":"object-assign-expects-data-objects","errorCode":null,"errorMessage":"Object.assign expects data objects.","messagePattern":"Object\\.assign expects data objects\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/stdlib/object.ts","lineNumber":45,"sourceCode":"      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        }\n        for (const [key, item] of Object.entries(value)) guardedSet(out, key, item)\n      }\n      return out\n    }\n    case \"fromEntries\": {\n      if (args[0] instanceof SandboxMap) {\n        const out: Record<string, unknown> = Object.create(null)\n        for (const [key, item] of args[0].map.entries()) guardedSet(out, coerceToString(key), item)\n        return out\n      }\n      if (args[0] instanceof SandboxURLSearchParams) {\n        const out: Record<string, unknown> = Object.create(null)\n        for (const [key, value] of args[0].params.entries()) guardedSet(out, key, value)\n        return out\n      }\n      const pairs = boundedData(args[0], \"Object.fromEntries input\")\n      if (!Array.isArray(pairs)) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/stdlib/object.ts#L27-L63","documentation":"The Object.assign branch validates every source argument is a plain data object (not null, undefined — those are skipped — not array, not primitive, not sandbox value) and throws this when a source fails the check, matching the assign-specific requireObject semantics.","triggerScenarios":"Object.assign({}, [1,2]) (array source), Object.assign({}, 42), Object.assign({}, 'str'), Object.assign(target, someArrayResponse) where an upstream call returned an array instead of an object.","commonSituations":"Merging defaults with an API result that is occasionally an array; spreading array-likes into config; a renamed endpoint changed the response shape from object to list.","solutions":["Wrap array sources: Object.assign({}, ...arr) → iterate and index-convert first, or Object.fromEntries(arr.map((v,i)=>[String(i),v]))","Skip/normalize scalar sources before merging: const src = (v) => (v && typeof v === 'object' && !Array.isArray(v) ? v : {})","Check the producing function/endpoint for a shape change and fix at the source","Merge only after validating each input with a plain-object check"],"exampleFix":"// before\nconst merged = Object.assign({}, defaults, apiResult)\n// after\nconst src = apiResult && typeof apiResult === 'object' && !Array.isArray(apiResult) ? apiResult : {}\nconst merged = Object.assign({}, defaults, src)","handlingStrategy":"validation","validationCode":"const asPlainObject = (v: unknown): Record<string, unknown> =>\n  v !== null && typeof v === 'object' && !Array.isArray(v) ? v as Record<string, unknown> : {}\nconst merged = Object.assign({}, asPlainObject(defaults), asPlainObject(apiResult))","typeGuard":"const isMergeSource = (v: unknown): v is Record<string, unknown> =>\n  v !== null && v !== undefined && typeof v === 'object' && !Array.isArray(v)","tryCatchPattern":"try {\n  return Object.assign({}, source)\n} catch (e) {\n  if (e instanceof InterpreterRuntimeError && e.message.includes('Object.assign expects data objects')) {\n    return Object.assign({}, normalizeSource(source))\n  }\n  throw e\n}","preventionTips":["Normalize each assign source to a plain object first","Watch endpoints whose response shape changed object→array","Skip null/undefined sources explicitly (assign already tolerates them)","Add shape assertions at API boundaries"],"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"}