antonmedv/fx · error · Error

Cannot get length of ${typeof x}

Error message

Cannot get length of ${typeof x}

What it means

len(x) is the standard-library length helper: it returns the length of arrays and strings, and the number of own keys of plain objects. When x is any other type (number, boolean, null, undefined, function, symbol, bigint), no branch matches and it throws 'Cannot get length of <type>'. The library intentionally fails fast instead of returning 0 or NaN so callers notice they applied a collection function to a scalar.

Source

Thrown at internal/engine/stdlib.js:30

        parts.push(JSON.stringify(arg, null, 2))
      }
    }
    println(parts.join(' '))
  },
}

const skip = Symbol('skip')

function apply(fn, ...args) {
  if (typeof fn === 'function') return fn(...args)
  return fn
}

function len(x) {
  if (Array.isArray(x)) return x.length
  if (typeof x === 'string') return x.length
  if (typeof x === 'object' && x !== null) return Object.keys(x).length
  throw new Error(`Cannot get length of ${typeof x}`)
}

function uniq(x) {
  if (Array.isArray(x)) return [...new Set(x)]
  throw new Error(`Cannot get unique values of ${typeof x}`)
}

function sort(x) {
  if (Array.isArray(x)) return x.sort()
  throw new Error(`Cannot sort ${typeof x}`)
}

function isFalsely(x) {
  return x === false || x === null || x === undefined
}

function filter(fn) {
  return function (x) {

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Check the value's type before calling len and handle scalars explicitly (e.g. len(x ?? []))
  2. Coerce or convert: String(x).length for strings, Object.keys(x ?? {}).length for possibly-null objects
  3. If x may be null/undefined from a lookup, default it first: len(x || [])
  4. Wrap the call in try/catch if the input type is genuinely dynamic and length is optional

Example fix

// before
const n = len(count)
// after
const n = typeof count === 'number' ? count : len(count ?? [])
Defensive patterns

Strategy: type-guard

Validate before calling

if (x == null || (typeof x !== 'string' && typeof x !== 'object')) throw new TypeError('len() requires an array, string, or object'); if (typeof x === 'object' && !Array.isArray(x) && Object.keys(x).length === 0) { /* empty object: len returns 0, fine */ }

Type guard

function hasLength(x) { return typeof x === 'string' || Array.isArray(x) || (x !== null && typeof x === 'object') }

Try / catch

let n; try { n = len(x) } catch (e) { if (e.message.startsWith('Cannot get length of')) { n = 0 } else { throw e } }

Prevention

When it happens

Trigger: Calling len(42), len(true), len(null), len(undefined), or len(() => {}) — any value that is not an Array, string, or non-null object.

Common situations: Pipelines where an upstream step sometimes yields null instead of an empty array/string (e.g. missing JSON field parsed as null, an API returning no data), or applying len to a number that a config/split function returned instead of a string.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02). Data as JSON: /api/errors/5c0ff5e6dd3b6af5. Report an issue: GitHub.