overleaf/overleaf · error · InvalidInsertionError

insertion must be a string

Error message

insertion must be a string

What it means

InsertOp represents an insertion of text into a document, so its `insertion` payload must be a string. The constructor explicitly type-checks and throws InvalidInsertionError when given a non-string (number, undefined, object, etc.). This fails fast so a malformed insert never propagates into document transforms.

Source

Thrown at libraries/overleaf-editor-core/lib/operation/scan_op.js:97

    throw new Error('abstract method')
  }

  toString() {
    'ScanOp'
  }
}

class InsertOp extends ScanOp {
  /**
   *
   * @param {string} insertion
   * @param {TrackingProps | undefined} tracking
   * @param {string[] | undefined} commentIds
   */
  constructor(insertion, tracking = undefined, commentIds = undefined) {
    super()
    if (typeof insertion !== 'string') {
      throw new InvalidInsertionError('insertion must be a string')
    }
    if (containsNonBmpChars(insertion)) {
      throw new InvalidInsertionError('insertion contains non-BMP characters')
    }
    /** @type {string} */
    this.insertion = insertion
    /** @type {TrackingProps | undefined} */
    this.tracking = tracking
    /** @type {string[] | undefined} */
    this.commentIds = commentIds
  }

  /**
   *
   * @param {RawInsertOp} op
   * @returns {InsertOp}
   */
  static fromJSON(op) {

View on GitHub (pinned to 28ad3b03b7)

Solutions

  1. Coerce or validate the insertion to a string before constructing: String(value) or a typeof check.
  2. If the value comes from JSON, use InsertOp.fromJSON(op) which validates the `i` property and gives a clearer error path.
  3. Fix the upstream code path producing undefined/null insertion values (often a missing field in fetched data).

Example fix

// before
new InsertOp(payload.insertion) // payload.insertion may be undefined
// after
if (typeof payload.insertion !== 'string') throw new TypeError('insertion required')
new InsertOp(payload.insertion)
Defensive patterns

Strategy: validation

Validate before calling

if (typeof insertion !== 'string') {
  throw new TypeError('insertion must be a string before building InsertOp')
}

Type guard

function isStringInsertion(v) { return typeof v === 'string' }

Try / catch

try {
  op = new InsertOp(insertion)
} catch (e) {
  if (e instanceof InvalidInsertionError && e.message.includes('must be a string')) {
    op = new InsertOp(String(insertion ?? ''))
  } else throw e
}

Prevention

When it happens

Trigger: Calling `new InsertOp(value)` where value is not a string: `new InsertOp(42)`, `new InsertOp(undefined)` after a failed lookup, or passing raw JSON like `{ i: 5 }` fields directly instead of going through fromJSON.

Common situations: Deserializing JSON where the insertion field is a number/null; constructing ops programmatically from computed values that turned out undefined; form/API input not coerced to string before building ops.

Related errors


AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03). Data as JSON: /api/errors/bb70c079774f97d5. Report an issue: GitHub.