FuelLabs/fuels-ts · error · NoWitnessAtIndexError

Witness at index "${index}" was not found

Error message

Witness at index "${index}" was not found

What it means

Thrown by `TransactionRequest.updateWitness(index, witness)` when no witness exists at the given array index. The method is meant to replace an existing witness in-place, so it guards with a truthiness check on `this.witnesses[index]` and rejects if the slot is empty. The error is surfaced via a dedicated `NoWitnessAtIndexError` class wrapping the index.

Source

Thrown at packages/account/src/providers/transaction-request/transaction-request.ts:323

   */
  updateWitnessByOwner(address: AddressInput, signature: BytesLike) {
    const ownerAddress = new Address(address);
    const witnessIndex = this.getCoinInputWitnessIndexByOwner(ownerAddress);
    if (typeof witnessIndex === 'number') {
      this.updateWitness(witnessIndex, signature);
    }
  }

  /**
   * Updates an existing witness without any side effects.
   *
   * @param index - The index of the witness to update.
   * @param witness - The new witness.
   * @throws If the witness does not exist.
   */
  updateWitness(index: number, witness: TransactionRequestWitness) {
    if (!this.witnesses[index]) {
      throw new NoWitnessAtIndexError(index);
    }
    this.witnesses[index] = witness;
  }

  /**
   * Helper function to add an external signature to the transaction.
   *
   * @param account - The account/s to sign to the transaction.
   * @returns The transaction with the signature witness added.
   */
  async addAccountWitnesses(account: Account | Account[]) {
    const accounts = Array.isArray(account) ? account : [account];
    await Promise.all(
      accounts.map(async (acc) => {
        this.addWitness((await acc.signTransaction(<TransactionRequestLike>this)) as string);
      })
    );

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Check `request.witnesses[index]` exists before calling `updateWitness`, or use `addWitness(witness)` if you intend to append a new witness.
  2. If reconstructing a request, ensure you re-add all original witnesses before updating any by index.
  3. Use `request.witnesses.length` to validate the index bounds before the call.

Example fix

// before
request.updateWitness(2, newWitness); // throws if only 1 witness exists
// after
if (request.witnesses[2]) {
  request.updateWitness(2, newWitness);
} else {
  request.addWitness(newWitness);
}
Defensive patterns

Strategy: validation

Validate before calling

function canUpdateWitness(req: TransactionRequest, index: number): boolean {
  return typeof req.witnesses[index] !== 'undefined';
}
if (canUpdateWitness(request, idx)) request.updateWitness(idx, witness); else request.addWitness(witness);

Type guard

null

Try / catch

try { request.updateWitness(idx, witness); } catch (e) { if (e instanceof NoWitnessAtIndexError) { request.addWitness(witness); } else throw e; }

Prevention

When it happens

Trigger: Calling `transactionRequest.updateWitness(i, witness)` where `i` is beyond the current `witnesses` array length, or before any witness was ever added at that index. Common in multi-signature flows that update a witness slot they assume was pre-populated.

Common situations: Re-signing a transaction after reconstructing it from JSON where witnesses were not preserved; calling updateWitness before `addWitness`/`addAccountWitnesses`; index arithmetic that overshoots the array (e.g. using witness count instead of the index).

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/7cbd968df59ee420. Report an issue: GitHub.