FuelLabs/fuels-ts · error · FuelError

MISSING_CONNECTOR

MISSING_CONNECTOR

Error message

A connector is required to sign messages.

What it means

Thrown by Account.signMessage when the account has no connector attached. The Account class signs via an injected FuelConnector (a wallet extension); without one it cannot produce a signature because it holds no private key material itself. This separates read-only/address-only accounts from sign-capable accounts.

Source

Thrown at packages/account/src/account.ts:1073

    });

    return {
      ...txCost,
      requiredQuantities,
    };
  }

  /**
   * Sign a message from the account via the connector.
   *
   * @param message - the message to sign.
   * @returns a promise that resolves to the signature.
   *
   * @hidden
   */
  async signMessage(message: HashableMessage): Promise<string> {
    if (!this._connector) {
      throw new FuelError(ErrorCode.MISSING_CONNECTOR, 'A connector is required to sign messages.');
    }
    return this._connector.signMessage(this.address.toString(), message);
  }

  /**
   * Signs a transaction from the account via the connector..
   *
   * @param transactionRequestLike - The transaction request to sign.
   * @returns A promise that resolves to the signature of the transaction.
   */
  async signTransaction(
    transactionRequestLike: TransactionRequestLike,
    connectorOptions: AccountSendTxParams = {}
  ): Promise<string | TransactionRequest> {
    if (!this._connector) {
      throw new FuelError(
        ErrorCode.MISSING_CONNECTOR,
        'A connector is required to sign transactions.'

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Use an unlocked wallet that holds a private key for signing: Wallet.fromPrivateKey or WalletUnlocked, instead of an address-only Account.
  2. If you intend to sign via an extension, call account.connect(fuelConnector) (or obtain the account from fuel.getWallet) before signMessage.
  3. Guard the call site: if (!account.connector) throw a clearer domain error explaining signing is unavailable.

Example fix

// before
const account = new Account(address, provider);
await account.signMessage(msg);

// after
const account = Wallet.fromPrivateKey(privateKey, provider);
await account.signMessage(msg);
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the account can sign before calling signMessage
async function canSign(account: Account): Promise<boolean> {
  return Boolean((account as any)._connector) || account instanceof BaseWalletUnlocked;
}

Type guard

import { BaseWalletUnlocked, Account } from 'fuels';

function isSignCapable(account: Account): boolean {
  return (account as any)._connector != null || account instanceof BaseWalletUnlocked;
}

Try / catch

try {
  const sig = await account.signMessage(message);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.MISSING_CONNECTOR) {
    // prompt user to connect wallet, or switch to WalletUnlocked
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing an Account or WalletLocked directly from an address (new Account(address, provider) or WalletLocked), then calling account.signMessage(msg). Also occurs if connect(connector) was never called, or the connector reference was cleared.

Common situations: Using a 'view-only' wallet instance (address only) for signing, forgetting to call account.connect(connector) after creation, or mixing up WalletLocked (address) with WalletUnlocked/BaAccount that can actually sign.

Related errors


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