{"record":{"id":"f8f8721fa87ca21e","repo":"different-ai/openwork","slug":"string-name-expects-argument-index-1-to-be-f8f872","errorCode":null,"errorMessage":"String.${name} expects argument ${index + 1} to be a number.","messagePattern":"String\\.(.+?) expects argument (.+?) to be a number\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/interpreter/runtime.ts","lineNumber":346,"sourceCode":"    return false\n  }\n  throw new InterpreterRuntimeError(\n    \"The right-hand side of 'instanceof' must be a constructor CodeMode knows: Error (or a specific error type like TypeError), Date, RegExp, Map, Set, URL, URLSearchParams, Array, Object, or Promise.\",\n    node,\n  )\n}\n\nconst invokeStringMethod = (value: string, name: string, args: Array<unknown>, node: AstNode): unknown => {\n  const str = (index: number): string => {\n    const arg = args[index]\n    if (typeof arg !== \"string\")\n      throw new InterpreterRuntimeError(`String.${name} expects argument ${index + 1} to be a string.`, node)\n    return arg\n  }\n  const num = (index: number): number => {\n    const arg = args[index]\n    if (typeof arg !== \"number\")\n      throw new InterpreterRuntimeError(`String.${name} expects argument ${index + 1} to be a number.`, node)\n    return arg\n  }\n  const optNum = (index: number): number | undefined => (args[index] === undefined ? undefined : num(index))\n  const optStr = (index: number): string | undefined => (args[index] === undefined ? undefined : str(index))\n\n  let result: unknown\n  switch (name) {\n    case \"toLowerCase\":\n      result = value.toLowerCase()\n      break\n    case \"toUpperCase\":\n      result = value.toUpperCase()\n      break\n    case \"trim\":\n      result = value.trim()\n      break\n    // trimLeft/trimRight are the legacy aliases of trimStart/trimEnd, kept because models write them.\n    case \"trimStart\":","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/interpreter/runtime.ts#L328-L364","documentation":"This sandboxed String method dispatcher validates that numeric arguments (indexes, counts, positions) are actual JavaScript numbers before calling the host String method. The library throws this instead of letting a non-number reach String.prototype methods so errors stay inside the interpreter runtime with the offending AST node attached. Argument index+1 in the message is 1-based to match how developers count method arguments.","triggerScenarios":"Calling a sandboxed String method whose numeric argument is a string, undefined non-optional, boolean, or object: e.g. String('abc').slice('0', 2), String('abc').indexOf(1), String('x').repeat('3'). Also happens when optNum forwards a defined non-number value.","commonSituations":"Porting JS written where values came from JSON with string-typed numbers ('3' instead of 3); forgetting parseInt on user input; passing null where a number was expected; mixing up argument order so a string lands in a numeric slot.","solutions":["Convert the argument with Number(), parseInt/parseFloat, or unary + before passing it","Check argument order so the numeric parameter receives the numeric value","Ensure the value is not undefined for a required numeric argument (optional slots use optNum and tolerate undefined)","Use typeof x === 'number' guards on dynamically sourced values"],"exampleFix":"// before\n\"hello sandbox\".slice(\"0\", 5)\n// after\n\"hello sandbox\".slice(Number(offset), 5) // offset coerced/validated as number","handlingStrategy":"type-guard","validationCode":"function assertNum(v, name) { if (typeof v !== \"number\") throw new TypeError(`${name} must be a number, got ${typeof v}`); return v }\nassertNum(index, \"index\"); s.slice(index, end)","typeGuard":"const isNum = (v) => typeof v === \"number\" && Number.isFinite(v)","tryCatchPattern":"try { r = s.slice(i, j) } catch (e) { if (String(e.message).includes(\"to be a number\")) { i = Number(i); j = Number(j); r = s.slice(i, j) } else throw e }","preventionTips":["Coerce external/JSON values with Number() before passing to String numeric args","Keep argument order aligned with the method signature","Use typeof checks at boundaries where user input flows in","Remember index+1 in the message is 1-based"],"tags":["codemode","interpreter","type-error","string-methods","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"}