Diagnosing Jule Module Resolution Failures: From Import Errors to Root Cause
Import errors in Jule builds almost always trace to six causes: stale jule.mod, version conflicts, path casing, missing vendor dirs, private-module credentials, or compiler skew. Here's how to tell them apart and fix each.
30 Dec 2025, 16:53 UTC

Your build stops at the import line: module not found, package not found, or an ambiguous-import complaint during jule build. The IDE underlines the import in red, and jule mod tidy refuses to resolve dependencies. In nearly every case the cause is one of six things — a missing or stale module file, a version conflict, a path-casing mismatch, an absent vendor directory, missing credentials for a private module, or a compiler version that predates the project's requirements. This guide walks through how to tell them apart and what to do for each.
Review note: Jule's toolchain is young and its commands evolve between releases. Verify each command below against jule help and the current documentation for your installed version before relying on it in CI.
Match the symptom to the cause
| What you see | Likely cause | First check |
|---|---|---|
| Cannot resolve any imports in a fresh clone | Missing or outdated jule.mod | Does jule.mod exist at the repo root? |
| "ambiguous import" or two versions of one module | Version conflict in the module graph | jule mod graph for duplicate paths |
| Builds on Windows/macOS, fails on Linux CI | Import path casing vs. directory casing | Compare import string to on-disk directory name |
| Fails only with vendored builds | Missing or stale vendor/ | Is vendor/ present and committed? |
Fails only on github.com/org/... imports | Private module without credentials | Check GOPRIVATE and git auth |
| Fails after pulling a project from elsewhere | Compiler version skew | jule version vs. project's toolchain line |
Ordered checks before changing anything
- Validate the module state. Run
jule mod verify(if supported in your version) to check downloaded modules against recorded checksums. A checksum failure points at a corrupted cache or a proxy problem, not your code. - Look for duplicate modules. Run
jule mod graphand filter for the failing path. Two different versions of the same module path confirm a version conflict. - Compare casing character by character. Print the import string and the actual directory under the module cache (
jule env GOMODCACHE) orvendor/. On Linux,github.com/Org/Modandgithub.com/org/modare different paths; on Windows and macOS they usually are not, which is why this bug only appears in CI. - Check the module cache is readable. Confirm the directory reported by
jule env GOMODCACHEexists and your user can read it. Permission problems here masquerade as "module not found." - Rebuild from a clean cache. Run
jule clean -modcache(or delete the cache directory manually) and thenjule mod download. This separates "corrupted local state" from "genuinely broken configuration." - Inspect
replacedirectives. Areplacewith a relative path like../local/modresolves relative to the module file's location and breaks when the build runs from a different working directory or a different checkout layout in CI.
Fixes matched to each finding
Missing or stale jule.mod
Initialize the module and let the tool populate requirements:
jule mod init example.com/myproject
jule mod tidyRun these at the repository root as your normal user. tidy rewrites jule.mod, so commit the result. If tidy itself fails on a specific import, that import is your real problem — move to the relevant section below.
Version conflict
Edit jule.mod so all paths that require the conflicting module agree on one version. If a transitive dependency pins an incompatible version, a replace directive can force a single version module-wide. Re-run jule mod graph afterwards and confirm exactly one version per module path.
Path casing mismatch
Prefer fixing the import string to match the directory's true casing. If the directory itself was created with the wrong case on a case-insensitive filesystem, a plain rename may not register in git; use git mv -f OldName newname (or a two-step rename through a temporary name) so the case change is committed. Verify on a Linux machine or in CI that the import now resolves.
Missing vendor directory
If your build uses vendoring, regenerate and commit it:
jule mod vendor
jule build -mod=vendor ./...The second command should succeed with the network disabled — that is the point of vendoring. Be aware that vendor/ copies all transitive dependencies and can grow a repository substantially on large dependency trees.
Private module credentials
Tell the toolchain which hosts are private so it skips the public proxy and checksum database for them, then give git a working credential. HTTPS with a token is generally more portable than SSH because CI systems can inject a token as a secret without key management:
jule env -w GOPRIVATE=github.com/myorg/*
GIT_TERMINAL_PROMPT=0 jule mod download github.com/myorg/private@v1.0.0The GIT_TERMINAL_PROMPT=0 prefix makes the failure immediate and explicit instead of hanging on a password prompt — useful in CI. If you use SSH, the same private key must exist in the CI environment, which is a common cause of "works locally, fails in CI."
Compiler version skew
Compare jule version against the toolchain requirement in the project's jule.mod (or its README/CI config). Treat a toolchain line as advisory: your CI must explicitly install the matching compiler version rather than assuming the directive enforces it. Pin the version in the CI pipeline so the build is reproducible.
Verifying the fix
Build a minimal reproduction in a scratch directory — a new module with a single file importing only the problematic dependency — and run jule mod tidy there. If the minimal case resolves, the fault is in your project's configuration (a stray replace, a stale lock of versions), not the dependency. If it fails identically, the fault is in the dependency, your credentials, or the toolchain. For casing issues, add a CI step that lists the module cache directory and confirms the on-disk path matches the import exactly.
When to escalate
- Checksum mismatch survives a clean cache and re-download. The proxy or upstream module is serving inconsistent content — report it to the proxy or module maintainer with the exact module path and version.
- The compiler crashes with an internal error on a module graph that
jule mod graphrenders cleanly. That is a compiler bug, not a configuration problem. Collect the version, the minimal reproduction, and the full error output, and file an issue with the Jule project. - A local-path
replaceworks on your machine but fails in CI due to checkout layout or symlink resolution. This is a known fragility of relative replaces, not something you misconfigured. The durable fix is vendoring or publishing the dependency properly; document the limitation if you must keep the replace.
Most module resolution failures in Jule come down to environment and configuration rather than the language tooling itself. Working the checks in order — verify, graph, casing, cache, clean rebuild, replace audit — isolates the layer at fault before you start editing files, which keeps the fix small and the diagnosis defensible.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.