jdx/mise · error · eyre::Report
Go workspace module {} is missing {GO_MOD}
Error message
Go workspace module {} is missing {GO_MOD} What it means
Raised by the Go workspace provider when a directory listed in go.work's use directives does not exist on disk (context.exists fails and the missing path does not resolve outside the workspace via symlink logic). The message points at the expected go.mod because every use entry must be a module directory containing one.
Source
Thrown at src/task/workspace/go.rs:63
for directory in module_directories {
let candidate = if directory.is_absolute() {
directory
} else {
workspace_root.join(directory)
};
let lexical_candidate = lexical_absolute(&candidate)?;
if !lexical_candidate.starts_with(&lexical_root)
&& !lexical_candidate.starts_with(&canonical_root)
{
continue;
}
let candidate = lexical_candidate;
if !context.exists(&candidate) {
if missing_path_resolves_outside(&candidate, &lexical_root, &canonical_root)? {
continue;
}
bail!(
"Go workspace module {} is missing {GO_MOD}",
candidate.display()
);
}
let canonical_module = context.canonicalize(&candidate).wrap_err_with(|| {
format!(
"failed to resolve Go workspace module {}",
candidate.display()
)
})?;
let Ok(relative) = canonical_module.strip_prefix(&canonical_root) else {
continue;
};
if !context.is_file(&canonical_module.join(GO_MOD)) {
bail!(
"Go workspace module {} is missing {GO_MOD}",
candidate.display()
);View on GitHub (pinned to 6f52dcdf99)
Solutions
- Drop the stale entry: `go work edit -dropuse ./svc/auth` (or edit go.work by hand)
- Restore or recreate the directory with `go mod init` if the module should still exist
- Regenerate the file with `go work use ./...` from the workspace root to rebuild an accurate use list
Example fix
# before (go.work)
go 1.23
use (
./api
./deleted-svc
)
# after
go 1.23
use (
./api
) Defensive patterns
Strategy: validation
Validate before calling
let go_work = std::fs::read_to_string("go.work")?;
for line in go_work.lines() {
let line = line.split("//").next().unwrap_or("").trim();
if let Some(arg) = line.strip_prefix("use ") {
for dir in arg.trim_matches(|c| c == '(' || c == ')').split_whitespace() {
let dir = dir.trim_matches('"');
if !std::path::Path::new(dir).exists() {
return Err(eyre::eyre!("go.work lists missing directory {dir}"));
}
}
}
} Type guard
fn go_work_use_dirs_exist(root: &Path) -> bool {
let Ok(contents) = std::fs::read_to_string(root.join("go.work")) else { return true; };
let mut in_block = false;
for raw in contents.lines() {
let line = raw.split("//").next().unwrap_or("").trim();
let arg = if in_block { line } else { line.strip_prefix("use ").map(str::trim).unwrap_or("") };
if arg == "(" { in_block = true; continue; }
if in_block && line == ")" { in_block = false; continue; }
if !arg.is_empty() && !root.join(arg.trim_matches('"')).exists() { return false; }
}
true
} Try / catch
Err(report) if report.to_string().contains("is missing go.mod") => {
// run the toolchain's own repair: `go work edit -dropuse <dir>`, then retry discovery
std::process::Command::new("go").args(["work", "edit", "-dropuse", dir]).status();
} Prevention
- After deleting or moving a module, immediately run `go work edit -dropuse ./old` or `go work use ./...`
- Run `go work sync` in CI to catch stale use entries early
- Treat go.work like a lockfile in code review: update it in the same commit as directory moves
When it happens
Trigger: go.work contains use ./svc/auth but svc/auth was deleted or renamed without running `go work edit -dropuse`; a stale go.work after moving a module; sparse/partial checkouts where the listed directory was not fetched.
Common situations: Deleting or moving a module directory and forgetting go.work; merging branches that move modules; CI with sparse checkout; manually trimming directories to speed builds.
Related errors
- unterminated use block
- failed to discover workspace providers: {error}
- workspace provider {provider_id:?} returned duplicate projec
- directive requires one argument
- unterminated interpreted Go string
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/5116ce5180488edc.
Report an issue: GitHub.