jdx/mise · error · eyre::Report

unterminated raw Go string

Error message

unterminated raw Go string

What it means

parse_argument treats arguments starting with a backtick as Go raw strings and requires a matching closing backtick; when strip_suffix('`') fails the token is an unterminated raw string and parsing aborts. Raw strings in go files span to the next backtick, so one unclosed delimiter consumes the rest of the line.

Source

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

    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())
}

fn unescape_go_string(value: &str) -> Result<String> {
    let mut characters = value.chars();
    let mut unescaped = String::new();
    while let Some(character) = characters.next() {
        if character == '"' {
            bail!("unexpected interpreted Go string delimiter");

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Add the closing backtick so the token is `./api` wrapped in a backtick pair, or drop the backticks entirely for simple paths
  2. Use interpreted quotes ("...") when the path contains no escapes; raw strings cannot contain any backtick at all
  3. Validate the file with `go work sync` / `go build` after editing

Example fix

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

# after
use ./api
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

fn is_closed_raw_string(token: &str) -> bool {
    token.strip_prefix('`').is_none_or(|body| body.ends_with('`'))
}

Try / catch

Err(report) if report.to_string().contains("unterminated raw Go string") => {
    // raw strings buy nothing for plain paths; strip the stray backtick and retry
    let token = token.trim_start_matches('`');
    directories.push(PathBuf::from(token));
}

Prevention

When it happens

Trigger: go.work or go.mod contains `use `./api` style entries where the closing backtick is missing; a single stray backtick line inside a use (...) block; paths edited with mismatched keyboard layouts producing the opener only.

Common situations: Copying Windows paths with backticks used as accidental quote substitutes; hand-adding quoting for paths with spaces; merge artifacts leaving a lone backtick.

Related errors


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