{"record":{"id":"39ed1638a46ae1d6","repo":"FuelLabs/fuels-rs","slug":"add-an-abigen-command","errorCode":null,"errorMessage":"Add an `Abigen(..)` command!","messagePattern":"Add an `Abigen\\(\\.\\.\\)` command!","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/fuels-macros/src/setup_program_test/parsing/validations.rs","lineNumber":25,"sourceCode":"use crate::{\n    parse_utils::ErrorsExt,\n    setup_program_test::parsing::{\n        AbigenCommand, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand,\n    },\n};\n\npub(crate) fn extract_the_abigen_command(\n    parent_span: Span,\n    abigen_commands: &[AbigenCommand],\n) -> Result<AbigenCommand> {\n    match abigen_commands {\n        [single_command] => Ok(single_command.clone()),\n        commands => {\n            let err = commands\n                .iter()\n                .map(|command| Error::new(command.span, \"Only one `Abigen` command allowed\"))\n                .combine_errors()\n                .unwrap_or_else(|| Error::new(parent_span, \"Add an `Abigen(..)` command!\"));\n\n            Err(err)\n        }\n    }\n}\n\npub(crate) fn validate_all_contracts_are_known(\n    abigen_command: &AbigenCommand,\n    deploy_commands: &[DeployContractCommand],\n) -> Result<()> {\n    extract_contracts_to_deploy(deploy_commands)\n        .difference(&names_of_program_bindings(\n            abigen_command,\n            ProgramType::Contract,\n        ))\n        .flat_map(|unknown_contract| {\n            [\n                Error::new_spanned(unknown_contract, \"Contract is unknown\"),","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/FuelLabs/fuels-rs/blob/d9a250a51818dda64bfeb5ef7cc19cf27bdcd623/packages/fuels-macros/src/setup_program_test/parsing/validations.rs#L7-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add exactly one Abigen(..) command listing the programs the test needs: Abigen(contracts = [...], scripts = [...]).","Ensure the identifier is spelled 'Abigen' so it parses as the Abigen command (otherwise error [12] fires instead).","If the test needs no bindings at all, remove the dependent commands too so the invocation is coherent."],"exampleFix":"// before\nsetup_program_test!(\n    Wallets([wallet]),\n)\n// after\nsetup_program_test!(\n    Wallets([wallet]),\n    Abigen(contracts = [(name = \"counter\", project = \"../counter\")]),\n)","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start every setup_program_test! from a template containing one Abigen command.","If removing Abigen, remove the DeployContract/LoadScript commands that depend on its bindings too."],"tags":["rust","macro","compile-time","setup-program-test","abigen"],"backgroundTag":null,"analyzedSha":"d9a250a51818dda64bfeb5ef7cc19cf27bdcd623","analyzedAt":"2026-08-16T09:49:30.618Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}