golang/go · error

unterminated %c string

Error message

unterminated %c string

What it means

Thrown by the Split function when a quoted string (delimited by either single ' or double " quotes) has no matching closing quote before end-of-input. The scanner advances past the opening quote character but reaches the end of the string without finding the same quote character again. The %c formats the unmatched quote character for identification.

Source

Thrown at src/cmd/internal/quoted/quoted.go:45

	// Quotes further inside the string do not count.
	var f []string
	for len(s) > 0 {
		for len(s) > 0 && isSpaceByte(s[0]) {
			s = s[1:]
		}
		if len(s) == 0 {
			break
		}
		// Accepted quoted string. No unescaping inside.
		if s[0] == '"' || s[0] == '\'' {
			quote := s[0]
			s = s[1:]
			i := 0
			for i < len(s) && s[i] != quote {
				i++
			}
			if i >= len(s) {
				return nil, fmt.Errorf("unterminated %c string", quote)
			}
			f = append(f, s[:i])
			s = s[i+1:]
			continue
		}
		i := 0
		for i < len(s) && !isSpaceByte(s[i]) {
			i++
		}
		f = append(f, s[:i])
		s = s[i:]
	}
	return f, nil
}

// Join joins a list of arguments into a string that can be parsed
// with Split. Arguments are quoted only if necessary; arguments
// without spaces or quotes are kept as-is. No argument may contain both

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Add the missing closing quote character to the input string.
  2. Validate input strings are properly balanced before passing to Split.
  3. Check for shell-escaping issues that may have consumed a quote character.

Example fix

// Before (broken): quoted.Split(`-foo 'bar`)
// After (fixed):  quoted.Split(`-foo 'bar'`)
Defensive patterns

Strategy: validation

Validate before calling

// Validate quote balance before calling Split:
func validateQuotes(s string) error {
    for i := 0; i < len(s); i++ {
        if s[i] == '\'' || s[i] == '"' {
            quote := s[i]
            found := false
            for j := i + 1; j < len(s); j++ {
                if s[j] == quote {
                    found = true
                    break
                }
            }
            if !found {
                return fmt.Errorf("unterminated %c quote at position %d", quote, i)
            }
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Input string starts with ' or " but the corresponding closing delimiter is absent. The for loop `for i < len(s) && s[i] != quote` exits because i >= len(s) without finding the closing quote.

Common situations: Malformed command-line flag values (e.g. cmd/link's -extldflags) where a quoted argument is missing its closing quote. Typographical errors in configuration strings, copy-paste issues, or shell-escaping mistakes that drop a closing quote.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/278c6b6f6b1163cd. Report an issue: GitHub.