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
- Read the appended inner message in the error string to determine the root cause (no configurables, wrong name, or encoding failure).
- Verify configurable names against factory.interface.configurables keys.
- Verify value types match the Sway configurable type — use the Interface's type encoding for complex types.
- 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
- Pre-validate configurable names against factory.interface.configurables before calling setConfigurableConstants.
- Ensure value types match the Sway configurable declaration — use the Interface to check expected types.
- Use the same ABI + bytecode pair from a single compilation to avoid encoding mismatches.
- This is the catch-all for errors 171 and 172 — the inner message distinguishes the root cause.
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
- CONFIGURABLE_NOT_FOUND
- CONFIGURABLE_NOT_FOUND
- FUNCTION_NOT_FOUND
- MISSING_PROVIDER
- CONTRACT_SIZE_EXCEEDS_LIMIT
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/1329c94694d2fbb5.
Report an issue: GitHub.