FuelLabs/fuels-ts · error · FuelError

INVALID_CONFIGURABLE_CONSTANTS

INVALID_CONFIGURABLE_CONSTANTS

Error message

Error setting configurable constants on contract: ${(<Error>err).message}.

What it means

The catch-all in ContractFactory.setConfigurableConstants() (packages/contract/src/contract-factory.ts:422). It wraps every error from the try block — including the inner CONFIGURABLE_NOT_FOUND throws (errors 171, 172) and any failure from interface.encodeConfigurable(), arrayify(), or bytes.set() — and re-throws as INVALID_CONFIGURABLE_CONSTANTS with the original error message appended. This is the error callers actually observe for any configurable-related failure.

Source

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

        if (!this.interface.configurables[key]) {
          throw new FuelError(
            ErrorCode.CONFIGURABLE_NOT_FOUND,
            `Contract does not have a configurable named: '${key}'`
          );
        }

        const { offset } = this.interface.configurables[key];

        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);

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Read the appended inner message in the error string to determine the root cause (no configurables, wrong name, or encoding failure).
  2. Verify configurable names against factory.interface.configurables keys.
  3. Verify value types match the Sway configurable type — use the Interface's type encoding for complex types.
  4. Ensure the ABI and bytecode are from the same compilation output.

Example fix

// before
await factory.deploy({ configurableConstants: { WRONG_NAME: 42 } });

// after
const configurables = factory.interface.configurables;
console.log('Available configurables:', Object.keys(configurables));
const validConfigurables = {};
for (const [key, value] of Object.entries(userConfigurables)) {
  if (key in configurables) validConfigurables[key] = value;
  else console.warn(`Skipping unknown configurable: ${key}`);
}
await factory.deploy({ configurableConstants: validConfigurables });
Defensive patterns

Strategy: try-catch

Validate before calling

const configurables = factory.interface.configurables;
const validKeys = Object.keys(configurables);

// Pre-validate all keys and types
const safeConfigurables: Record<string, unknown> = {};
for (const [key, value] of Object.entries(userConfigurables)) {
  if (!validKeys.includes(key)) {
    throw new Error(`Unknown configurable '${key}'. Valid: ${validKeys.join(', ')}`);
  }
  safeConfigurables[key] = value;
}

if (Object.keys(safeConfigurables).length === 0 && validKeys.length === 0) {
  throw new Error('Contract has no configurables');
}

factory.setConfigurableConstants(safeConfigurables);

Type guard

function allConfigurablesExist(factory: ContractFactory, input: Record<string, unknown>): boolean {
  const valid = Object.keys(factory.interface.configurables);
  return Object.keys(input).every(k => valid.includes(k));
}

Try / catch

try {
  factory.setConfigurableConstants(configurables);
} catch (e) {
  if (e instanceof FuelError && e.code === 'invalid-configurable-constants') {
    // The inner error message is appended; parse it for root cause
    const msg = e.message;
    if (msg.includes('does not have configurables')) {
      // no configurables in ABI
    } else if (msg.includes('does not have a configurable named')) {
      // wrong key name
    } else {
      // encoding error from encodeConfigurable
    }
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling setConfigurableConstants() (directly or via deploy with configurableConstants) when: the contract has no configurables (error 171 path), a provided key doesn't exist in the ABI (error 172 path), the value cannot be ABI-encoded by encodeConfigurable(), the bytecode offset is out of range, or arrayify/bytes.set fails.

Common situations: Wrong configurable name or value type; ABI/bytecode from different compilations; providing a value whose type doesn't match the Sway configurable type (e.g. passing a number where a struct is expected); encoding errors from malformed ABI types.

Related errors


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