Skip to content

Sonatina internal error: duplicate root object main across ingot modules #1478

Description

@g-r-a-n-t

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions