jdx/mise · error · eyre::Report

unterminated interpreted Go string

Error message

unterminated interpreted Go string

What it means

parse_argument treats arguments starting with a double quote as Go interpreted strings and requires a matching closing double quote; strip_suffix('"') failing raises this error. The quoted use/module argument was opened but never closed, so the token cannot be tokenized as one path.

Source

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

    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");
    }
    if let Some(value) = value.strip_prefix('"') {
        let Some(value) = value.strip_suffix('"') else {
            bail!("unterminated interpreted Go string");
        };
        return unescape_go_string(value);
    }
    if let Some(value) = value.strip_prefix('`') {
        let Some(value) = value.strip_suffix('`') else {
            bail!("unterminated raw Go string");
        };
        if value.contains('`') {
            bail!("unexpected raw Go string delimiter");
        }
        return Ok(value.to_string());
    }
    if value.split_whitespace().count() != 1 {
        bail!("directive requires exactly one argument");
    }
    Ok(value.to_string())
}

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Close the string: `use "./api"`
  2. Only quote when the path actually contains spaces or special characters; plain `use ./api` needs no quotes
  3. Re-run `go work sync` to have the toolchain report the malformed line as well

Example fix

# before (go.work)
use "./api

# after
use "./api"
Defensive patterns

Strategy: validation

Validate before calling

fn quotes_balanced(token: &str) -> bool {
    if let Some(body) = token.strip_prefix('"') {
        body.ends_with('"')
    } else {
        true
    }
}

for dir in use_arguments { assert!(quotes_balanced(dir)); }

Type guard

fn is_closed_interpreted_string(token: &str) -> bool {
    token.strip_prefix('"').is_none_or(|body| body.ends_with('"') && !body.ends_with("\\\""))
}

Try / catch

Err(report) if report.to_string().contains("unterminated interpreted Go string") => {
    // quote is optional for simple paths: strip the dangling opener and retry
    let token = token.trim_start_matches('"');
    directories.push(PathBuf::from(token));
}

Prevention

When it happens

Trigger: go.work contains `use "./api` (opening quote, no closer); inside a `use (...)` block a line consisting of a single stray `"`; a truncated line where the trailing quote was cut off.

Common situations: Typing a quote intending to handle a path with spaces and forgetting the closer; partial copy-paste of an entry; editor auto-pairing being disabled or deleted by a later edit.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/f7fd979081d25716. Report an issue: GitHub.