Skip to content

package_test produces a unexpected circular dependency error #4530

@aeddi

Description

@aeddi

Unexpected circular dependency error with package_test

Description

The issue occurs when using a test package located in the same directory as the package to be tested, with the name simply suffixed by _test:

  • a package importee is imported by a package importer
  • a package importee_test is located in the same directory as importee
  • importee_test imports the package importer

The following error occurs when starting the node: unable to load examples folder: sorting packages: cycle detected: gno.land/r/issue/importee.

Your environment

  • Go version: go1.24.1
  • OS and CPU architecture: darwin/arm64
  • Gno commit hash causing the issue: 34ba1ef

Steps to reproduce

Using a gnolang node

  1. Create the files below
  2. Run gnolang start --lazy
Files

examples/gno.land/r/issue/importer/gnomod.toml

module = "gno.land/r/issue/importer"
gno = "0.9"

examples/gno.land/r/issue/importer/importer.gno

package importer

import (
	"gno.land/r/issue/importee"
)

func Function() {
	importee.Function()
}

examples/gno.land/r/issue/importee/gnomod.toml

module = "gno.land/r/issue/importee"
gno = "0.9"

examples/gno.land/r/issue/importee/importee.gno

package importee

func Function() {}

examples/gno.land/r/issue/importee/importee_test.gno

package importee_test

import (
	"testing"

	"gno.land/r/issue/importee"
	"gno.land/r/issue/importer" // <- this import will be considered circular
)

func TestFunction(_ *testing.T) {
	importee.Function()
	importer.Function()
}

Using a txtar

  1. Create the txtar below
  2. Run cd gno.land/pkg/integration && go test -v -run=TestTestdata/issue_xxx
File

gno.land/pkg/integration/testdata/issue_xxx.txtar

# Load packages from $WORK directory.
loadpkg gno.land/r/issue/importee $WORK/importee
loadpkg gno.land/r/issue/importer $WORK/importer

# Start the node
gnoland start
stdout 'node started successfully'

-- importer/gnomod.toml --
module = "gno.land/r/issue/importer"
gno = "0.9"

-- importer/importer.gno --
package importer

import (
	"gno.land/r/issue/importee"
)

func Function() {
	importee.Function()
}

-- importee/gnomod.toml --
module = "gno.land/r/issue/importee"
gno = "0.9"

-- importee/importee.gno --
package importee

func Function() {}

-- importee/importee_test.gno --
package importee_test

import (
	"testing"

	"gno.land/r/issue/importee"
	"gno.land/r/issue/importer" // <- this import will be produce an error
)

func TestFunction(_ *testing.T) {
	importee.Function()
	importer.Function()
}

Expected behaviour

Neither of these two cases should produce an error.

Actual behaviour

Using a gnolang node

The node produce this error: sorting packages: cycle detected: gno.land/r/issue/importee

Using a txtar

The error is slightly different in this case: invalid gno package; type check errors:\ngno.land/r/issue/importee/importee_test.gno:7:2: could not import gno.land/r/issue/importer (unknown import path "gno.land/r/issue/importer")

Logs

Full gnolang node logs
gno.land % gnoland start --lazy
Default configuration initialized at /Users/aeddi/Code/gno/gno.land/gnoland-data/config/config.toml
WARN: Initialized default node config at "/Users/aeddi/Code/gno/gno.land/gnoland-data/config"

Validator private key saved at /Users/aeddi/Code/gno/gno.land/gnoland-data/secrets/priv_validator_key.json
Validator last sign state saved at /Users/aeddi/Code/gno/gno.land/gnoland-data/secrets/priv_validator_state.json
Node key saved at /Users/aeddi/Code/gno/gno.land/gnoland-data/secrets/node_key.json
WARN: Initialized default node secrets at "/Users/aeddi/Code/gno/gno.land/gnoland-data/secrets"
unable to initialize genesis.json, unable to generate genesis file, unable to load examples folder: sorting packages: cycle detected: gno.land/r/issue/importee
Full txtar logs
integration % go test -v -run=TestTestdata/issue_xxx
=== RUN   TestTestdata
=== PAUSE TestTestdata
=== CONT  TestTestdata
=== RUN   TestTestdata/issue_xxx
=== PAUSE TestTestdata/issue_xxx
=== CONT  TestTestdata/issue_xxx
    testscript.go:584: WORK=$WORK
        PATH=/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/golang.org/[email protected]/bin:/Users/aeddi/.asdf/installs/golang/1.23.6/go/bin:/Users/aeddi/.asdf/installs/golang/1.23.6/packages/bin:/Users/aeddi/Library/Android/sdk/build-tools/34.0.0:/Users/aeddi/Library/Android/sdk/cmdline-tools/latest/bin:/Users/aeddi/Library/Android/sdk/platform-tools:/Users/aeddi/.asdf/shims:/opt/homebrew/opt/asdf/libexec/bin:/opt/homebrew/sbin:/opt/homebrew/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Applications/Keybase.app/Contents/SharedSupport/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/iTerm.app/Contents/Resources/utilities:/Users/aeddi/.antigen/bundles/zsh-users/zsh-history-substring-search:/Users/aeddi/.antigen/bundles/zsh-users/zsh-syntax-highlighting:/Users/aeddi/.antigen/bundles/zsh-users/zsh-autosuggestions:/Users/aeddi/.antigen/bundles/zsh-users/zsh-completions:/Users/aeddi/.antigen/bundles/Tarrasch/zsh-bd
        GOTRACEBACK=system
        HOME=/no-home
        TMPDIR=$WORK/.tmp
        devnull=/dev/null
        /=/
        :=:
        $=$
        exe=
        UPDATE_SCRIPTS=false
        TESTWORK=false
        test1_user_seed=source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast
        test1_user_addr=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5
        GNO_DBDIR=/var/folders/04/4sgwgm3j0rj_2ml_r0_88p_r0000gn/T/TestTestdata1266032078/002
        SID=40661fcc
        GNOROOT=/Users/aeddi/Code/gno
        GNOHOME=/var/folders/04/4sgwgm3j0rj_2ml_r0_88p_r0000gn/T/TestTestdata1266032078/001/gno

        # Load packages from $WORK directory. (0.000s)
        > loadpkg gno.land/r/issue/importee $WORK/importee
        "gno.land/r/issue/importee" package was added to genesis
        > loadpkg gno.land/r/issue/importer $WORK/importer
        "gno.land/r/issue/importer" package was added to genesis
        # Start the node (2.722s)
        > gnoland start
        time=2025-07-18T12:53:47.868+02:00 level=ERROR msg="Unable to deliver genesis tx" log="msg:0,success:false,log:--= Error =--\nData: vm.TypeCheckError{abciError:vm.abciError{}, Errors:[]string{\"gno.land/r/issue/importee/importee_test.gno:7:2: could not import gno.land/r/issue/importer (unknown import path \\\"gno.land/r/issue/importer\\\")\"}}\nMsg Traces:\nStack Trace:\n    0  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/errors.go:81\n    1  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/keeper.go:387\n    2  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/handler.go:42\n    3  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/handler.go:29\n    4  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:672\n    5  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:863\n    6  /Users/aeddi/Code/gno/tm2/pkg/sdk/helpers.go:35\n    7  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:417\n    8  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:318\n    9  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:346\n   10  /Users/aeddi/Code/gno/tm2/pkg/bft/abci/client/local_client.go:196\n   11  /Users/aeddi/Code/gno/tm2/pkg/bft/appconn/app_conn.go:66\n   12  /Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:305\n   13  /Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:263\n   14  /Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:239\n   15  /Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:392\n   16  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/node_inmemory.go:145\n   17  /Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:103\n   18  /Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:316\n   19  /Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/golang.org/[email protected]/src/runtime/asm_arm64.s:1223\n--= /Error =--\n,events:[]" error="invalid gno package; type check errors:\ngno.land/r/issue/importee/importee_test.gno:7:2: could not import gno.land/r/issue/importer (unknown import path \"gno.land/r/issue/importer\")" gas-used=27734
        [stderr]
        panic: msg:0,success:false,log:--= Error =--
        	Data: vm.TypeCheckError{abciError:vm.abciError{}, Errors:[]string{"gno.land/r/issue/importee/importee_test.gno:7:2: could not import gno.land/r/issue/importer (unknown import path \"gno.land/r/issue/importer\")"}}
        	Msg Traces:
        	Stack Trace:
        	    0  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/errors.go:81
        	    1  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/keeper.go:387
        	    2  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/handler.go:42
        	    3  /Users/aeddi/Code/gno/gno.land/pkg/sdk/vm/handler.go:29
        	    4  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:672
        	    5  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:863
        	    6  /Users/aeddi/Code/gno/tm2/pkg/sdk/helpers.go:35
        	    7  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:417
        	    8  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:318
        	    9  /Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:346
        	   10  /Users/aeddi/Code/gno/tm2/pkg/bft/abci/client/local_client.go:196
        	   11  /Users/aeddi/Code/gno/tm2/pkg/bft/appconn/app_conn.go:66
        	   12  /Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:305
        	   13  /Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:263
        	   14  /Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:239
        	   15  /Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:392
        	   16  /Users/aeddi/Code/gno/gno.land/pkg/gnoland/node_inmemory.go:145
        	   17  /Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:103
        	   18  /Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:316
        	   19  /Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/golang.org/[email protected]/src/runtime/asm_arm64.s:1223
        	--= /Error =--
        	,events:[]

        goroutine 11 [running]:
        github.com/gnolang/gno/gno.land/pkg/gnoland.PanicOnFailingTxResultHandler({{0x1019aa9c0, 0x1400e43c7b0}, 0x2, {0x1019a9da0, 0x1400059d1a0}, {0x1019aabb8, 0x14000198000}, {0x140005a4740, 0xf}, {0x0, ...}, ...}, ...)
        	/Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:276 +0x94
        github.com/gnolang/gno/gno.land/pkg/gnoland.InitChainerConfig.loadAppState({0x101993b70, {0x14000382420, 0x23}, _, _, {_, _}, {_, _}, {_, ...}, ...}, ...)
        	/Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:433 +0x658
        github.com/gnolang/gno/gno.land/pkg/gnoland.InitChainerConfig.InitChainer({_, {_, _}, _, _, {_, _}, {_, _}, {_, ...}, ...}, ...)
        	/Users/aeddi/Code/gno/gno.land/pkg/gnoland/app.go:318 +0x26c
        github.com/gnolang/gno/tm2/pkg/sdk.(*BaseApp).InitChain(0x1400045ec60, {{}, {0x974d660, 0xee00c1eb9, 0x0}, {0x140005a4740, 0xf}, 0x1400059d180, {0x1400047c150, 0x1, ...}, ...})
        	/Users/aeddi/Code/gno/tm2/pkg/sdk/baseapp.go:346 +0x290
        github.com/gnolang/gno/tm2/pkg/bft/abci/client.(*localClient).InitChainSync(0x14000518688?, {{}, {0x974d660, 0xee00c1eb9, 0x0}, {0x140005a4740, 0xf}, 0x1400059d180, {0x1400047c150, 0x1, ...}, ...})
        	/Users/aeddi/Code/gno/tm2/pkg/bft/abci/client/local_client.go:196 +0x138
        github.com/gnolang/gno/tm2/pkg/bft/appconn.(*consensus).InitChainSync(0x10?, {{}, {0x974d660, 0xee00c1eb9, 0x0}, {0x140005a4740, 0xf}, 0x1400059d180, {0x1400047c150, 0x1, ...}, ...})
        	/Users/aeddi/Code/gno/tm2/pkg/bft/appconn/app_conn.go:66 +0xc0
        github.com/gnolang/gno/tm2/pkg/bft/consensus.(*Handshaker).ReplayBlocks(_, {{0x10142270b, 0xb}, {0x10142270b, 0xb}, {0x1016f6cf0, 0x0}, {0x140005a4740, 0xf}, 0x0, ...}, ...)
        	/Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:305 +0xa00
        github.com/gnolang/gno/tm2/pkg/bft/consensus.(*Handshaker).Handshake(0x14011a27058, {0x1019b7740, 0x14000618600})
        	/Users/aeddi/Code/gno/tm2/pkg/bft/consensus/replay.go:263 +0x378
        github.com/gnolang/gno/tm2/pkg/bft/node.doHandshake({_, _}, {{0x10142270b, 0xb}, {0x10142270b, 0xb}, {0x1016f6cf0, 0x0}, {0x140005a4740, 0xf}, ...}, ...)
        	/Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:239 +0x134
        github.com/gnolang/gno/tm2/pkg/bft/node.NewNode(0x1400045e480, {0x1019a89c0, 0x1400000e2b8}, 0x14000118640, {0x1090142f0, 0x1400000e480}, 0x140004b7aa0, 0x79c4d52982fca1ea?, {0x1019b7640, 0x140003fc0e0}, ...)
        	/Users/aeddi/Code/gno/tm2/pkg/bft/node/node.go:392 +0x2a8
        github.com/gnolang/gno/gno.land/pkg/gnoland.NewInMemoryNode(0x14000118310, 0x140000e6180)
        	/Users/aeddi/Code/gno/gno.land/pkg/gnoland/node_inmemory.go:145 +0x5a4
        github.com/gnolang/gno/gno.land/pkg/integration.RunNode({0x1019aab48, 0x14000477ec0}, 0x14000506300, {0x10199ec38, 0x1400007a040}, {0x0?, 0x0?})
        	/Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:103 +0x5b0
        github.com/gnolang/gno/gno.land/pkg/integration.RunMain.func1()
        	/Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:316 +0x40
        created by github.com/gnolang/gno/gno.land/pkg/integration.RunMain in goroutine 1
        	/Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:315 +0x278

        FAIL: testdata/issue_xxx.txtar:6:
        	Error Trace:	/Users/aeddi/Code/gno/gno.land/pkg/integration/process.go:346
        	            				/Users/aeddi/Code/gno/gno.land/pkg/integration/testscript_gnoland.go:689
        	            				/Users/aeddi/Code/gno/gno.land/pkg/integration/testscript_gnoland.go:340
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:740
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:759
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:739
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:632
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:369
        	            				/Users/aeddi/.asdf/installs/golang/1.23.6/packages/pkg/mod/github.com/rogpeppe/[email protected]/testscript/testscript.go:239
        	Error:      	Received unexpected error:
        	            	waiting for readiness: process exited without 'READY'
        	Test:       	issue_xxx


--- FAIL: TestTestdata (0.02s)
    --- FAIL: TestTestdata/issue_xxx (3.03s)
FAIL
exit status 1
FAIL	github.com/gnolang/gno/gno.land/pkg/integration	3.434s

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐞 bugSomething isn't working

    Type

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions