dagger/dagger · error
invalid key %q: unescaped control character in quoted path s
Error message
invalid key %q: unescaped control character in quoted path segment
What it means
This error is thrown by the workspace config key parser (parseBasicConfigPathSegment) when a double-quoted path segment in a config key contains a raw control character (ASCII < 0x20 or DEL 0x7f) that is not expressed as an escape sequence such as \t, \n, or \u00XX. The parser rejects raw control bytes to keep key strings unambiguous and printable.
Source
Thrown at core/workspace/config.go:1093
func parseBasicConfigPathSegment(key string, start int) (string, int, error) {
var b strings.Builder
for i := start; i < len(key); {
ch := key[i]
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':View on GitHub (pinned to 82ba2681db)
Solutions
- Replace the raw control character with its escape: use \t, \n, \r, \f, \b, \" or \\ inside the quoted segment
- Use a \uXXXX (or \UXXXXXXXX) escape for control characters without a short form
- Remove the accidental control character if it was not intentional
Example fix
// before
setConfig("ignore ed", []string{"*.log"})
// after
setConfig("ignore\ted", []string{"*.log"}) Defensive patterns
Strategy: validation
Validate before calling
func hasRawControl(key string) bool {
for _, r := range key {
if r < 0x20 || r == 0x7f {
return true
}
}
return false
}
// before calling: if hasRawControl(key) { /* escape or reject */ } Type guard
func isSafeConfigKey(key string) bool {
for _, r := range key {
if r < 0x20 || r == 0x7f {
return false
}
}
return key != ""
} Try / catch
if err := writeConfig(key, val); err != nil {
if strings.Contains(err.Error(), "unescaped control character") {
// re-escape key and retry once
}
return err
} Prevention
- Escape control characters as \t \n \uXXXX when building keys
- Never interpolate raw multi-line strings into config keys
- Sanitize keys with a whitelist of allowed characters
When it happens
Trigger: Calling the config-write API with a key like "ignore ed" or "my\nkey.x" where a double-quoted segment contains a literal tab, newline, or other control character instead of its backslash escape.
Common situations: Keys built by string concatenation or template interpolation that accidentally embed a newline or tab; copying a key from a JSON/YAML file where escapes were not carried over; pasting multi-line text into a key field.
Related errors
- invalid key %q: trailing escape in quoted path segment
- invalid key %q: invalid escape in quoted path segment
- invalid key %q: unterminated quoted path segment
- invalid key %q: incomplete unicode escape in quoted path seg
- invalid key %q: invalid unicode escape in quoted path segmen
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/21d744073286e8de.
Report an issue: GitHub.