krisk/Fuse · error · Error

Invalid doc index: must be a non-negative integer within the

Error message

Invalid doc index: must be a non-negative integer within the bounds of the docs array

What it means

Thrown by FuseIndex.add when docIndex is not an integer or is negative, violating the contract that each doc is added at a valid non-negative integer position within the docs array. The index stores records keyed by this position, so an invalid value would corrupt bookkeeping (e.g. the inverted index).

Source

Thrown at src/tools/FuseIndex.ts:93

      }
    } else {
      // List is Array<Object>
      for (let i = 0; i < len; i++) {
        this.records[recordCount++] = this._createObjectRecord(this.docs[i], i)
      }
    }

    this.records.length = recordCount
    this.norm.clear()
  }
  // Appends a record for `doc` at `docIndex` (the doc's position in the source
  // array). Returns the appended record, or null when `doc` is a blank string
  // (those are skipped at record creation; see `_createStringRecord`). Callers
  // use the return value to gate downstream bookkeeping like the inverted
  // index, which must not be touched when no record was produced.
  add(doc: T, docIndex: number): IndexRecord | null {
    if (!Number.isInteger(docIndex) || docIndex < 0) {
      throw new Error(ErrorMsg.INVALID_DOC_INDEX)
    }

    if (isString(doc)) {
      const record = this._createStringRecord(
        doc as unknown as string,
        docIndex
      )
      if (record) {
        this.records.push(record)
      }
      return record
    }

    const record = this._createObjectRecord(doc, docIndex)
    this.records.push(record)
    return record
  }
  // Removes the record for the doc at the specified source-array (docs) index.

View on GitHub (pinned to edf2fb608e)

Solutions

  1. Pass the correct array position: docs.length - 1 for the last appended item, or track the index explicitly when splicing.
  2. Guard before calling: if (!Number.isInteger(i) || i < 0) skip or fix the index.
  3. Use docs.push(doc) and add(doc, docs.length - 1) together so the indices stay in sync.
  4. Compute indices with Math.floor/parseInt from strings, never parseFloat or raw string arithmetic.

Example fix

// before
const idx = docs.indexOf(doc); index.add(doc, idx) // -1 when absent
// after
const idx = docs.indexOf(doc)
if (idx === -1) { docs.push(doc); index.add(doc, docs.length - 1) } else { index.add(doc, idx) }
Defensive patterns

Strategy: validation

Validate before calling

function canAdd(docs, doc, i) { return Number.isInteger(i) && i >= 0 && i < docs.length; }
if (!canAdd(docs, doc, i)) throw new Error('bad docIndex: ' + i);

Type guard

function isValidDocIndex(i: unknown): i is number {
  return typeof i === 'number' && Number.isInteger(i) && i >= 0;
}

Try / catch

try {
  const rec = index.add(doc, i);
} catch (e) {
  if (String(e.message).includes('Invalid doc index')) {
    // recompute the index from the docs array and retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling index.add(doc, docIndex) with a negative number, a float (e.g. 1.5), NaN, or a non-number coerced through arithmetic — Number.isInteger check fails. (Note: passing an index >= docs.length does not throw here; the bounds clause applies to the documented contract/other paths.)

Common situations: Manually maintaining a docs array while removing items and computing the next index with a stale length; off-by-one after splicing (length-2 used as next index becomes -1 on empty array); parsing doc indices from strings with parseFloat instead of parseInt.

Related errors


AI-assisted analysis of krisk/Fuse@edf2fb608e (2026-09-02). Data as JSON: /api/errors/f28c4934f3397ffa. Report an issue: GitHub.