fe build fails with an internal Sonatina error when an ingot contains 2+ source modules that don’t define a contract (e.g. “library/re-export” modules). It appears each such module is lowered into an EVM object named main, and multiple such modules collide.
Environment
fe: 26.1.0
- OS: Linux x86_64 (Ubuntu 24.04.1; kernel
6.17.0-23-generic)
Minimal repro
Create a new ingot with multiple library modules and a contract:
fe.toml
[ingot]
name = "dup_main_repro"
version = "0.1.0"
src/lib.fe
pub use libmod::{self, *}
pub use libmod2::{self, *}
pub use contractmod::{self, *}
src/libmod.fe
pub fn helper() -> u256 { 1 }
src/libmod2.fe
pub fn helper2() -> u256 { 2 }
src/contractmod.fe
pub msg AMsg {
#[selector = sol("foo()")]
Foo -> u256,
}
pub contract A {
recv AMsg {
Foo -> u256 { 1 }
}
}
Repro commands:
fe check <dir>: succeeds
fe build <dir>: fails
Actual result
Error: Failed to compile Sonatina bytecode: internal error: duplicate root object `main` across ingot modules
Evidence (IR contains multiple object @main)
The build can emit Sonatina IR successfully, and the .sona contains multiple main objects:
fe build <dir> --emit ir --out-dir <out-ir>
rg -n '^object @main' <out-ir>/dup_main_repro.sona
Output includes 2 matches (two object @main { ... } blocks).
Workarounds / related behavior
fe build <dir> --contract A succeeds.
- If the ingot has exactly one non-contract module,
fe build <dir> succeeds but emits extra out/main.bin / out/main.runtime.bin artifacts alongside the contract artifacts.
- Real-world example: the
chz ingot has two non-contract re-export modules (src/chess.fe and src/contracts.fe), so fe build . fails but fe build . --contract <Name> works.
Expected result
Any of the following would resolve the issue:
- Do not lower non-contract modules into deployable EVM “main” objects when building an ingot.
- Or ensure those objects are uniquely named/mangled per module so multi-file ingots build.
- Or gate emission of such “main” objects behind an explicit flag/target mode.
fe buildfails with an internal Sonatina error when an ingot contains 2+ source modules that don’t define acontract(e.g. “library/re-export” modules). It appears each such module is lowered into an EVM object namedmain, and multiple such modules collide.Environment
fe: 26.1.06.17.0-23-generic)Minimal repro
Create a new ingot with multiple library modules and a contract:
fe.tomlsrc/lib.fesrc/libmod.fesrc/libmod2.fesrc/contractmod.feRepro commands:
fe check <dir>: succeedsfe build <dir>: failsActual result
Evidence (IR contains multiple
object @main)The build can emit Sonatina IR successfully, and the
.sonacontains multiplemainobjects:Output includes 2 matches (two
object @main { ... }blocks).Workarounds / related behavior
fe build <dir> --contract Asucceeds.fe build <dir>succeeds but emits extraout/main.bin/out/main.runtime.binartifacts alongside the contract artifacts.chzingot has two non-contract re-export modules (src/chess.feandsrc/contracts.fe), sofe build .fails butfe build . --contract <Name>works.Expected result
Any of the following would resolve the issue: