FuelLabs/fuels-ts · error · FuelError

ACCOUNT_REQUIRED

ACCOUNT_REQUIRED

Error message

Account not assigned to contract.

What it means

Thrown by the private ContractFactory.getAccount() (packages/contract/src/contract-factory.ts:431) when this.account is null. An Account is required for any operation that submits transactions (deploy, assembleTx, getMaxChunkSize). The account is set during construction only if the third argument has a 'provider' property (duck-typed as a Wallet/Account); if a bare Provider or null is passed, this.account stays null.

Source

Thrown at packages/contract/src/contract-factory.ts:431

        const encoded = this.interface.encodeConfigurable(key, value as InputValue);

        const bytes = arrayify(this.bytecode);

        bytes.set(encoded, offset);

        this.bytecode = bytes;
      });
    } catch (err) {
      throw new FuelError(
        ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,
        `Error setting configurable constants on contract: ${(<Error>err).message}.`
      );
    }
  }

  private getAccount(): Account {
    if (!this.account) {
      throw new FuelError(ErrorCode.ACCOUNT_REQUIRED, 'Account not assigned to contract.');
    }
    return this.account;
  }

  private async prepareDeploy(deployOptions: DeployContractOptions) {
    const { configurableConstants } = deployOptions;

    if (configurableConstants) {
      this.setConfigurableConstants(configurableConstants);
    }

    const { contractId, transactionRequest } = this.createTransactionRequest(deployOptions);

    await this.assembleTx(transactionRequest, deployOptions);

    return {
      contractId,
      transactionRequest,

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Construct the ContractFactory with a Wallet/Account: new ContractFactory(bytecode, abi, wallet).
  2. Ensure the passed object exposes a 'provider' property — the SDK duck-types Accounts by checking 'provider' in accountOrProvider.
  3. If you only have a provider, obtain a Wallet from it first: Wallet.fromPrivateKey(pk, provider) or Wallet.generate({ provider }).

Example fix

// before
const factory = new ContractFactory(bytecode, abi, provider);
await factory.deploy();

// after
const factory = new ContractFactory(bytecode, abi, wallet);
await factory.deploy();
Defensive patterns

Strategy: validation

Validate before calling

const factory = new ContractFactory(bytecode, abi, provider);
if (!factory.account) {
  throw new Error('No account bound to ContractFactory. Pass a Wallet/Account as the 3rd argument.');
}
await factory.deploy();

Type guard

function hasAccount(factory: ContractFactory): factory is ContractFactory & { account: Account } {
  return factory.account !== null && factory.account !== undefined;
}

Try / catch

try {
  await factory.deploy();
} catch (e) {
  if (e instanceof FuelError && e.code === 'account-required') {
    // Factory was created with a Provider, not an Account
    const factoryWithAccount = new ContractFactory(bytecode, abi, wallet);
    await factoryWithAccount.deploy();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Constructing a ContractFactory with a Provider (not an Account/Wallet) or with null as the third argument, then calling deploy(), deployAsCreateTx(), deployAsBlobTx(), or any method that internally calls getAccount().

Common situations: Creating a factory for read-only inspection (connected to a Provider only) and then accidentally calling a deploy method; refactoring from provider-only to account-bound deployment; forgetting to pass the wallet; testing with a mock provider that lacks the 'provider' property.

Related errors


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