jdx/mise · error

Go module metadata contains multiple module directives

Error message

Go module metadata contains multiple module directives

What it means

When reading a Go module file's metadata, mise collects the value of each `module` directive. This error is thrown if more than one `module` line is found, since a Go module must declare exactly one module path. The parser refuses to guess which path is authoritative.

Source

Thrown at src/task/workspace/go.rs:164

    }
    Ok(directories)
}

fn read_module_path(context: &WorkspaceDiscoveryContext, path: &Path) -> Result<String> {
    let contents = context
        .read_to_string(path)
        .wrap_err_with(|| format!("failed to read Go module metadata {}", path.display()))?;
    let mut module_path = None;

    for (index, raw_line) in contents.lines().enumerate() {
        let line = strip_comment(raw_line).trim();
        let Some(arguments) = directive_arguments(line, "module") else {
            continue;
        };
        let parsed = parse_argument(arguments)
            .wrap_err_with(|| format!("invalid module directive on line {}", index + 1))?;
        if module_path.replace(parsed).is_some() {
            bail!("Go module metadata contains multiple module directives");
        }
    }

    module_path.ok_or_else(|| eyre::eyre!("Go module metadata is missing a module directive"))
}

fn directive_arguments<'a>(line: &'a str, directive: &str) -> Option<&'a str> {
    let rest = line.strip_prefix(directive)?;
    if !rest.starts_with(char::is_whitespace) {
        return None;
    }
    Some(rest.trim())
}

fn parse_argument(value: &str) -> Result<String> {
    if value.is_empty() {
        bail!("directive requires one argument");
    }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Remove the duplicate `module` line so exactly one remains
  2. If the file is generated, regenerate it from a single canonical source and diff before committing
  3. Check git history to see which module path is correct and delete the other

Example fix

// before (go.mod)
module example.com/app
module example.com/app/v2
// after
module example.com/app
Defensive patterns

Strategy: validation

Validate before calling

fn validate_single_module(contents: &str) -> Result<()> {
    let count = contents.lines().filter(|l| l.trim_start().starts_with("module ")).count();
    anyhow::ensure!(count <= 1, "expected at most one module directive, found {count}");
    Ok(())
}

Prevention

When it happens

Trigger: `read_module_path` iterating lines of a go.mod-like file via `directive_arguments(line, "module")` and encountering a second `module <path>` line after one was already parsed.

Common situations: Duplicated module lines after a bad merge or copy-paste in a go.mod; concatenating two module files; generated tooling appending a module directive without removing the old one.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/7664b7ef1f961ce3. Report an issue: GitHub.