FuelLabs/fuels-rs · error · syn::Error

Add an `Abigen(..)` command!

Error message

Add an `Abigen(..)` command!

What it means

Compile-time validation error from setup_program_test: extract_the_abigen_command found zero Abigen(...) commands. This is the fallback branch of the same match that rejects multiple Abigen commands — with an empty list there are no command spans to attach errors to, so the error is placed on the macro's parent span with a call to action.

Source

Thrown at packages/fuels-macros/src/setup_program_test/parsing/validations.rs:25

use crate::{
    parse_utils::ErrorsExt,
    setup_program_test::parsing::{
        AbigenCommand, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand,
    },
};

pub(crate) fn extract_the_abigen_command(
    parent_span: Span,
    abigen_commands: &[AbigenCommand],
) -> Result<AbigenCommand> {
    match abigen_commands {
        [single_command] => Ok(single_command.clone()),
        commands => {
            let err = commands
                .iter()
                .map(|command| Error::new(command.span, "Only one `Abigen` command allowed"))
                .combine_errors()
                .unwrap_or_else(|| Error::new(parent_span, "Add an `Abigen(..)` command!"));

            Err(err)
        }
    }
}

pub(crate) fn validate_all_contracts_are_known(
    abigen_command: &AbigenCommand,
    deploy_commands: &[DeployContractCommand],
) -> Result<()> {
    extract_contracts_to_deploy(deploy_commands)
        .difference(&names_of_program_bindings(
            abigen_command,
            ProgramType::Contract,
        ))
        .flat_map(|unknown_contract| {
            [
                Error::new_spanned(unknown_contract, "Contract is unknown"),

View on GitHub (pinned to d9a250a518)

Solutions

  1. Add exactly one Abigen(..) command listing the programs the test needs: Abigen(contracts = [...], scripts = [...]).
  2. Ensure the identifier is spelled 'Abigen' so it parses as the Abigen command (otherwise error [12] fires instead).
  3. If the test needs no bindings at all, remove the dependent commands too so the invocation is coherent.

Example fix

// before
setup_program_test!(
    Wallets([wallet]),
)
// after
setup_program_test!(
    Wallets([wallet]),
    Abigen(contracts = [(name = "counter", project = "../counter")]),
)
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A setup_program_test! invocation that contains other commands (Wallets, DeployContract, ...) but no Abigen command at all; or one where the Abigen block was deleted or commented out while its consumers remain.

Common situations: Starting a test from a stripped template; removing Abigen because bindings seemed unused, while DeployContract/LoadScript commands still reference generated types; a typo'd command name (e.g. 'AbiGen') being rejected as unrecognized before this check runs.

Related errors


AI-assisted analysis of FuelLabs/fuels-rs@d9a250a518 (2026-08-16). Data as JSON: /api/errors/39ed1638a46ae1d6. Report an issue: GitHub.