{"record":{"id":"1329c94694d2fbb5","repo":"FuelLabs/fuels-ts","slug":"invalid-configurable-constants-1329c9","errorCode":"INVALID_CONFIGURABLE_CONSTANTS","errorMessage":"Error setting configurable constants on contract: ${(<Error>err).message}.","messagePattern":"Error setting configurable constants on contract: (.+?)\\.","errorType":"exception","errorClass":"FuelError","httpStatus":null,"severity":"error","filePath":"packages/contract/src/contract-factory.ts","lineNumber":422,"sourceCode":"        if (!this.interface.configurables[key]) {\n          throw new FuelError(\n            ErrorCode.CONFIGURABLE_NOT_FOUND,\n            `Contract does not have a configurable named: '${key}'`\n          );\n        }\n\n        const { offset } = this.interface.configurables[key];\n\n        const encoded = this.interface.encodeConfigurable(key, value as InputValue);\n\n        const bytes = arrayify(this.bytecode);\n\n        bytes.set(encoded, offset);\n\n        this.bytecode = bytes;\n      });\n    } catch (err) {\n      throw new FuelError(\n        ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,\n        `Error setting configurable constants on contract: ${(<Error>err).message}.`\n      );\n    }\n  }\n\n  private getAccount(): Account {\n    if (!this.account) {\n      throw new FuelError(ErrorCode.ACCOUNT_REQUIRED, 'Account not assigned to contract.');\n    }\n    return this.account;\n  }\n\n  private async prepareDeploy(deployOptions: DeployContractOptions) {\n    const { configurableConstants } = deployOptions;\n\n    if (configurableConstants) {\n      this.setConfigurableConstants(configurableConstants);","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/FuelLabs/fuels-ts/blob/b3f37c91aca4aa9d5e4c0d3967f66237190826ea/packages/contract/src/contract-factory.ts#L404-L440","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait factory.deploy({ configurableConstants: { WRONG_NAME: 42 } });\n\n// after\nconst configurables = factory.interface.configurables;\nconsole.log('Available configurables:', Object.keys(configurables));\nconst validConfigurables = {};\nfor (const [key, value] of Object.entries(userConfigurables)) {\n  if (key in configurables) validConfigurables[key] = value;\n  else console.warn(`Skipping unknown configurable: ${key}`);\n}\nawait factory.deploy({ configurableConstants: validConfigurables });","handlingStrategy":"try-catch","validationCode":"const configurables = factory.interface.configurables;\nconst validKeys = Object.keys(configurables);\n\n// Pre-validate all keys and types\nconst safeConfigurables: Record<string, unknown> = {};\nfor (const [key, value] of Object.entries(userConfigurables)) {\n  if (!validKeys.includes(key)) {\n    throw new Error(`Unknown configurable '${key}'. Valid: ${validKeys.join(', ')}`);\n  }\n  safeConfigurables[key] = value;\n}\n\nif (Object.keys(safeConfigurables).length === 0 && validKeys.length === 0) {\n  throw new Error('Contract has no configurables');\n}\n\nfactory.setConfigurableConstants(safeConfigurables);","typeGuard":"function allConfigurablesExist(factory: ContractFactory, input: Record<string, unknown>): boolean {\n  const valid = Object.keys(factory.interface.configurables);\n  return Object.keys(input).every(k => valid.includes(k));\n}","tryCatchPattern":"try {\n  factory.setConfigurableConstants(configurables);\n} catch (e) {\n  if (e instanceof FuelError && e.code === 'invalid-configurable-constants') {\n    // The inner error message is appended; parse it for root cause\n    const msg = e.message;\n    if (msg.includes('does not have configurables')) {\n      // no configurables in ABI\n    } else if (msg.includes('does not have a configurable named')) {\n      // wrong key name\n    } else {\n      // encoding error from encodeConfigurable\n    }\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["contract","configurables","abi","catch-all","deployment","encoding"],"backgroundTag":null,"analyzedSha":"b3f37c91aca4aa9d5e4c0d3967f66237190826ea","analyzedAt":"2026-08-12T20:30:56.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}