different-ai/openwork · error · InterpreterRuntimeError

Number.toString radix must be between 2 and 36.

Error message

Number.toString radix must be between 2 and 36.

What it means

Number.prototype.toString(radix) only accepts an integer radix between 2 and 36 (digits 0-9 and a-z). CodeMode validates this range explicitly and throws this error for out-of-range radices (1, 0, negative, or > 36) instead of letting the engine raise a less descriptive RangeError.

Source

Thrown at packages/codemode/src/stdlib/number.ts:30

    return arg
  }
  let result: unknown
  switch (name) {
    case "toFixed":
      result = value.toFixed(optNum(0))
      break
    case "toExponential":
      result = value.toExponential(optNum(0))
      break
    case "toPrecision": {
      const digits = optNum(0)
      result = digits === undefined ? value.toString() : value.toPrecision(digits)
      break
    }
    case "toString": {
      const radix = optNum(0)
      if (radix !== undefined && (radix < 2 || radix > 36)) {
        throw new InterpreterRuntimeError("Number.toString radix must be between 2 and 36.", node)
      }
      result = value.toString(radix)
      break
    }
    default:
      throw new InterpreterRuntimeError(`Number method '${name}' is not available in CodeMode.`, node)
  }
  return boundedData(result, `Number.${name} result`)
}

export const invokeNumberStatic = (name: string, args: Array<unknown>, node: AstNode): unknown => {
  const value = args[0]
  switch (name) {
    case "isInteger":
      return Number.isInteger(value)
    case "isFinite":
      return Number.isFinite(value)
    case "isNaN":

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Use a radix in 2..36; for base-64 output use btoa or a base64 library, not toString(64).
  2. Clamp or validate the radix before calling: if (radix < 2 || radix > 36) throw new RangeError(...).
  3. If the radix comes from user config, sanitize it at load time to a safe default like 10.

Example fix

// before
const encoded = value.toString(64)
// after
const encoded = btoa(String(value))
Defensive patterns

Strategy: validation

Validate before calling

const safeRadix = (r: number | undefined) => { if (r === undefined) return undefined; if (!Number.isInteger(r) || r < 2 || r > 36) throw new RangeError(`radix ${r} out of range 2..36`); return r }

Type guard

const isValidRadix = (r: unknown): r is number => typeof r === "number" && Number.isInteger(r) && r >= 2 && r <= 36

Try / catch

try { return value.toString(radix) } catch (e) { if (/radix must be between 2 and 36/.test(String(e))) return value.toString(10); throw e }

Prevention

When it happens

Trigger: Calling value.toString(1), value.toString(0), value.toString(-2), value.toString(64) — any radix outside [2, 36] passed as the optional argument.

Common situations: Confusing base-64 encoding with a toString radix (toString does not do base64); computing a radix dynamically with an off-by-one (base 1 for 'unary'); porting code from bigint libs that accept radix 64.

Related errors


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