different-ai/openwork · error · InterpreterRuntimeError

Object.${name} is not available in CodeMode.

Error message

Object.${name} is not available in CodeMode.

What it means

invokeObjectMethod whitelists the Object statics available in CodeMode (keys, values, entries, hasOwn, assign, fromEntries). Any other Object static, or one reached through a name not in objectStatics, throws this before any argument work happens.

Source

Thrown at packages/codemode/src/stdlib/object.ts:9

import { type AstNode, InterpreterRuntimeError } from "../interpreter/model.js"
import { isBlockedMember } from "../tool-runtime.js"
import { isSandboxValue, SandboxMap, SandboxURLSearchParams } from "../values.js"
import { boundedData, coerceToString } from "./value.js"

export const objectStatics = new Set(["keys", "values", "entries", "hasOwn", "assign", "fromEntries"])

export const invokeObjectMethod = (name: string, args: Array<unknown>, node: AstNode): unknown => {
  if (!objectStatics.has(name)) throw new InterpreterRuntimeError(`Object.${name} is not available in CodeMode.`, node)
  const requireObject = (): Record<string, unknown> => {
    const value = boundedData(args[0], `Object.${name} input`)
    if (isSandboxValue(value)) return {}
    if (value === null || typeof value !== "object" || Array.isArray(value)) {
      throw new InterpreterRuntimeError(`Object.${name} expects a data object.`, node)
    }
    return value as Record<string, unknown>
  }
  const guardedSet = (out: Record<string, unknown>, key: string, item: unknown): void => {
    if (isBlockedMember(key)) throw new InterpreterRuntimeError(`Property '${key}' is not available in CodeMode.`, node)
    out[key] = item
  }
  switch (name) {
    case "keys": {
      const value = boundedData(args[0], "Object.keys input")
      if (isSandboxValue(value)) return []
      if (Array.isArray(value)) return Object.keys(value)
      if (value === null || typeof value !== "object") {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Restructure the script to use only Object.keys/values/entries/hasOwn/assign/fromEntries
  2. Implement the needed operation manually, e.g. clone via Object.assign({}, o) instead of Object.create/defineProperties
  3. Avoid Object.freeze entirely — the sandbox does not need mutation locking
  4. If a static is broadly useful, add it to objectStatics and implement its case in invokeObjectMethod

Example fix

// before
const clone = Object.create(Object.getPrototypeOf(src)); Object.assign(clone, src)
// after
const clone = Object.assign({}, src)
Defensive patterns

Strategy: validation

Validate before calling

const objectStatics = new Set(['keys','values','entries','hasOwn','assign','fromEntries'])
if (!objectStatics.has(fnName)) throw new Error(`Object.${fnName} unsupported in CodeMode`)
if (arg === null || typeof arg !== 'object') throw new Error('Object static requires an object')

Type guard

const isPlainObject = (v: unknown): v is Record<string, unknown> =>
  v !== null && typeof v === 'object' && !Array.isArray(v)

Try / catch

try {
  return Object[fnName](target)
} catch (e) {
  if (e instanceof InterpreterRuntimeError && /Object\..+ is not available/.test(e.message)) {
    return manualObjectOperation(fnName, target)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling Object.getOwnPropertyNames(o), Object.freeze(o), Object.entries via a typo like Object.Entries, Object.create, Object.setPrototypeOf, or Object.getPrototypeOf inside a CodeMode script.

Common situations: Porting utility code that mutates/freeze objects for safety; cloning logic using Object.assign misspellings or Object.getOwnPropertyDescriptors; generated code assuming full Node Object API.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/e236cb5c030b590a. Report an issue: GitHub.