dagger/dagger · error

invalid key %q: unterminated quoted path segment

Error message

invalid key %q: unterminated quoted path segment

What it means

parseBasicConfigPathSegment throws this when a double-quoted path segment in a config key is never closed with a matching double-quote before the end of the key string. The parser reached the end of input while still inside the quoted segment.

Source

Thrown at core/workspace/config.go:1098

		i++
		switch ch {
		case '\\':
			r, next, err := parseConfigPathEscape(key, i)
			if err != nil {
				return "", 0, err
			}
			b.WriteRune(r)
			i = next
		case '"':
			return b.String(), i, nil
		default:
			if ch < 0x20 || ch == 0x7f {
				return "", 0, fmt.Errorf("invalid key %q: unescaped control character in quoted path segment", key)
			}
			b.WriteByte(ch)
		}
	}
	return "", 0, fmt.Errorf("invalid key %q: unterminated quoted path segment", key)
}

func parseConfigPathEscape(key string, start int) (rune, int, error) {
	if start >= len(key) {
		return 0, 0, fmt.Errorf("invalid key %q: trailing escape in quoted path segment", key)
	}

	escaped := key[start]
	next := start + 1
	switch escaped {
	case 'b':
		return '\b', next, nil
	case 't':
		return '\t', next, nil
	case 'n':
		return '\n', next, nil
	case 'f':
		return '\f', next, nil

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Add the missing closing double-quote at the end of the segment
  2. If the segment should contain a literal quote, escape it as \"
  3. For segments needing no escape processing, use single-quote literal syntax: 'segment'

Example fix

// before
setConfig(""ignore.nested, value) // missing closing quote
// after
setConfig("ignore.nested", value)
Defensive patterns

Strategy: validation

Validate before calling

func quotesBalanced(key string) bool {
	inBasic, inLiteral := false, false
	for i := 0; i < len(key); i++ {
		switch {
		case inBasic && key[i] == '\\':
			i++
		case inBasic && key[i] == '"':
			inBasic = false
		case !inLiteral && key[i] == '"':
			inBasic = true
		case !inBasic && key[i] == '\'':
			inLiteral = !inLiteral
		}
	}
	return !inBasic && !inLiteral
}

Try / catch

if err := writeConfig(key, val); err != nil {
	if strings.Contains(err.Error(), "unterminated quoted path segment") {
		return fmt.Errorf("key %q is missing a closing quote", key)
	}
	return err
}

Prevention

When it happens

Trigger: Passing a key like "ignore.foo (missing closing quote) or a key where an unescaped \\ swallowed the closing quote, e.g. "ignore\" leaving the segment open.

Common situations: Hand-written keys with a dropped closing quote; template-generated keys where a variable containing a quote shifted quoting; shell quoting stripped one of the quotes before it reached the API.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/2f2a1b6c5bace820. Report an issue: GitHub.