{"record":{"id":"941246298f5a8056","repo":"different-ai/openwork","slug":"string-name-expects-argument-index-1-to-be","errorCode":null,"errorMessage":"String.${name} expects argument ${index + 1} to be a string.","messagePattern":"String\\.(.+?) expects argument (.+?) to be a string\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/interpreter/runtime.ts","lineNumber":340,"sourceCode":"    }\n  }\n  if (rhs instanceof PromiseNamespace) return lhs instanceof SandboxPromise\n  // Number/String/Boolean wrap primitives in JS; no boxed values exist in CodeMode, so\n  // `x instanceof Number` is always false - exactly what it is for primitives in JS.\n  if (rhs instanceof CoercionFunction && (rhs.name === \"Number\" || rhs.name === \"String\" || rhs.name === \"Boolean\")) {\n    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()","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/interpreter/runtime.ts#L322-L358","documentation":"The interpreter's invokeStringMethod helper defines a local `str(index)` accessor that asserts a positional argument of a String prototype method is a string before use. When a script calls a string method (e.g. replace, startsWith) with a non-string argument where the implementation requires one (1-based index in the message), it throws this InterpreterRuntimeError pointing at the call's AST node. It enforces string-typed arguments rather than relying on implicit coercion.","triggerScenarios":"Calling a string method with a number, object, or undefined where a string argument is required, e.g. `\"abc\".startsWith(1)` or `\"a-b\".replace(1, \"x\")` in a CodeMode script.","commonSituations":"Concatenating numbers instead of stringifying them before passing to string methods, LLM-generated scripts mixing types, or refactors that changed an argument from string to number.","solutions":["Convert the argument explicitly with String(arg), template literals, or .toString() before passing it to the string method.","Check the argument at the reported position (index + 1) in the failing method call and confirm its runtime type.","For numeric inputs, pass the number to the numeric-aware variants or coerce once at the boundary of your script.","Add a small helper that normalizes arguments before string method calls when scripts are generated dynamically."],"exampleFix":"// before\n\"hello world\".startsWith(104)\n// after\n\"hello world\".startsWith(String(104))","handlingStrategy":"type-guard","validationCode":"const isString = (v: unknown): v is string => typeof v === \"string\"\n// guard call sites before running:\nif (!isString(pattern) || !isString(replacement)) throw new Error(\"String method args must be strings\")","typeGuard":"const asStringArg = (v: unknown): string =>\n  typeof v === \"string\" ? v : String(v)","tryCatchPattern":"try {\n  await program(script)\n} catch (e) {\n  const m = /String\\.(\\w+) expects argument (\\d+) to be a string/.exec(e instanceof Error ? e.message : \"\")\n  if (m) {\n    console.error(`Method String.${m[1]} got a non-string for argument ${m[2]}; coerce with String() before calling.`)\n  } else throw e\n}","preventionTips":["Wrap string-method arguments in String(...) when values may be numbers or objects.","Interpolate numbers into template literals instead of passing them directly.","Lint generated scripts for string methods called with non-literal first arguments.","Keep script data conversions at the boundary: stringify inputs once before the script runs."],"tags":["interpreter","string-methods","type-mismatch","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"}