{"record":{"id":"a72dc24aab546921","repo":"FuelLabs/fuels-ts","slug":"abi-main-method-missing-a72dc2","errorCode":"ABI_MAIN_METHOD_MISSING","errorMessage":"Cannot use ABI without \"main\" function.","messagePattern":"Cannot use ABI without \"main\" function\\.","errorType":"validation","errorClass":"FuelError","httpStatus":null,"severity":"error","filePath":"packages/account/src/predicate/predicate.ts","lineNumber":215,"sourceCode":"\n  /**\n   * Processes the predicate data and returns the altered bytecode and interface.\n   *\n   * @param bytes - The bytes of the predicate.\n   * @param jsonAbi - The JSON ABI of the predicate.\n   * @param configurableConstants - Optional configurable constants for the predicate.\n   * @returns An object containing the new predicate bytes and interface.\n   */\n  private static processPredicateData(\n    bytes: BytesLike,\n    jsonAbi: JsonAbi,\n    configurableConstants?: { [name: string]: unknown }\n  ) {\n    let predicateBytes = arrayify(bytes);\n    const abiInterface: Interface = new Interface(jsonAbi);\n\n    if (abiInterface.functions.main === undefined) {\n      throw new FuelError(\n        ErrorCode.ABI_MAIN_METHOD_MISSING,\n        'Cannot use ABI without \"main\" function.'\n      );\n    }\n\n    if (configurableConstants && Object.keys(configurableConstants).length) {\n      predicateBytes = Predicate.setConfigurableConstants(\n        predicateBytes,\n        configurableConstants,\n        abiInterface\n      );\n    }\n\n    return {\n      predicateBytes,\n      predicateInterface: abiInterface,\n    };\n  }","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/FuelLabs/fuels-ts/blob/b3f37c91aca4aa9d5e4c0d3967f66237190826ea/packages/account/src/predicate/predicate.ts#L197-L233","documentation":"Thrown by Predicate.processPredicateData when the JSON ABI supplied to a Predicate does not declare a function named 'main'. Fuel predicates must expose a single entrypoint called main that returns a boolean; the SDK uses it to encode configurable constants and to reason about the predicate interface. Without it, the predicate cannot be executed on-chain.","triggerScenarios":"Instantiating new Predicate({ abi, bytecode, ... }) where abi.functions has no 'main' entry; passing the ABI of a regular contract (which may have arbitrary function names) instead of a predicate ABI; passing an ABI from a Sway predicate compiled with a renamed main function; passing an empty or stub ABI.","commonSituations":"Building a Predicate from a contract ABI by mistake (contracts use arbitrary names, predicates use main); ABI file is from an older/different Sway compiler version that emitted a different entrypoint name; abi file path resolved to the wrong JSON; forja/typescript output mixed up between contract and predicate folders.","solutions":["Confirm the ABI is from a Sway predicate program (sway-project type 'predicate'), not a contract.","Open the ABI JSON and verify a top-level functions array contains an object with name: 'main'.","Recompile the predicate with forc build and ensure the entrypoint is declared as fn main() -> bool (or the SDK-expected signature).","Point the Predicate constructor at the correct abi JSON file generated alongside the predicate bytecode."],"exampleFix":"// before — abi is a contract ABI with no main()\nconst predicate = new Predicate({ bytecode, abi: contractAbi });\n\n// after — use the predicate's own ABI (has functions: [{ name: 'main', ... }])\nconst predicate = new Predicate({ bytecode, abi: predicateAbi });","handlingStrategy":"validation","validationCode":"function hasMainFunction(abi: { functions?: Array<{ name: string }> }): boolean {\n  return Array.isArray(abi.functions) && abi.functions.some(f => f.name === 'main');\n}\n// call: if (!hasMainFunction(abi)) throw new Error('ABI must declare main() for a predicate');","typeGuard":"function isPredicateAbi(abi: any): abi is { functions: Array<{ name: 'main' }> } {\n  return Array.isArray(abi?.functions) && abi.functions.some((f: any) => f?.name === 'main');\n}","tryCatchPattern":"import { FuelError, ErrorCode } from '@fuel-ts/errors';\ntry {\n  const predicate = new Predicate({ bytecode, abi });\n} catch (e) {\n  if (e instanceof FuelError && e.code === ErrorCode.ABI_MAIN_METHOD_MISSING) {\n    // load the predicate ABI instead of the contract ABI and retry\n  }\n  throw e;\n}","preventionTips":["Keep predicate and contract ABIs in separate folders.","Assert abi.functions has 'main' before constructing a Predicate.","Recompile predicates with forc and use the generated ABI directly."],"tags":["predicate","abi","sway","validation"],"backgroundTag":null,"analyzedSha":"b3f37c91aca4aa9d5e4c0d3967f66237190826ea","analyzedAt":"2026-08-12T20:30:56.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}