antonmedv/fx · error · Error

Cannot delete key from ${typeof x}

Error message

Cannot delete key from ${typeof x}

What it means

del(key) is curried: del(key)(x) returns a copy of x with the key removed — splicing index `key` for arrays, or delete copy[key] for plain objects. The inner throw 'Cannot delete key from <type>' fires when x is neither an array nor a non-null object (string, number, boolean, null, undefined).

Source

Thrown at internal/engine/stdlib.js:179

    for (const y of x) console.log(y)
    return skip
  }
  throw new Error(`Cannot list ${typeof x}`)
}

function del(key) {
  return function (x) {
    if (Array.isArray(x)) {
      const copy = [...x]
      copy.splice(key, 1)
      return copy
    }
    if (typeof x === 'object' && x !== null) {
      const copy = {...x}
      delete copy[key]
      return copy
    }
    throw new Error(`Cannot delete key from ${typeof x}`)
  }
}

function exit(code) {
  __exit__(code)
}

function save(x) {
  if (typeof x === 'undefined') throw new Error('Cannot save undefined')
  __save__(__stringify__(x, null, 2))
  return x
}

function toBase64(x) {
  return __toBase64__(x)
}

function fromBase64(x) {

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Coerce null to an empty object before deleting: del(key)(x ?? {})
  2. Verify the target is an object (typeof x === 'object' && x !== null) before applying
  3. If a nested path may be absent, guard the whole expression: x?.user ?? {}
  4. Try/catch when input shape is dynamic

Example fix

// before
const safe = del('password')(record)
// after
const safe = del('password')(record ?? {})
Defensive patterns

Strategy: fallback

Validate before calling

const target = del(key); if (x == null || (typeof x !== 'object' && !Array.isArray(x))) throw new TypeError('del() target must be an array or object; got ' + (x === null ? 'null' : typeof x))

Type guard

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

Try / catch

let out; try { out = del(key)(x) } catch (e) { if (e.message.startsWith('Cannot delete key from')) { out = x } else { throw e } }

Prevention

When it happens

Trigger: del('password')(null), del(0)('abc'), del('k')(42), del('k')(undefined) — applying the returned deleter to a primitive; often the record being cleaned was null because the lookup failed.

Common situations: Sanitizing config/API payloads where an expected nested object is missing (null), redacting secrets from a record that turned out to be a scalar, or a pipeline stage that already unwrapped the object.

Related errors


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