databendlabs/databend · error
Expected to have terminated string literal after escaped…
Error message
Expected to have terminated string literal after escaped char '\' .
What it means
Thrown by `CursorReadStringExt::read_quoted_text` when it encounters a backslash escape character but the cursor is exhausted immediately after it — i.e. the input ends with a dangling `\` and no character follows to unescape. The parser requires an escape sequence to be complete inside a quoted string literal.
Solutions
- Escape the trailing backslash by doubling it: `C:\\` instead of `C:\`.
- Check the source string for a trailing '\' and append a second backslash before parsing.
- If the input comes from an external system, verify it was not truncated before the closing quote.
Example fix
// before let input = r#""C:\""#; // dangling escape // after let input = r#""C:\\""#; // escaped backslash
Defensive patterns
Strategy: validation
Validate before calling
fn has_dangling_escape(s: &str) -> bool {
s.chars().rev().take_while(|c| *c == '\\').count() % 2 == 1
} Type guard
fn ends_with_complete_escape(s: &str) -> bool {
!has_dangling_escape(s)
} Try / catch
match read_quoted_text(&mut buf) {
Ok(s) => s,
Err(e) if e.to_string().contains("escaped char") => {
// input ended with a lone backslash; fix or reject
Err(e)
}
Err(e) => Err(e),
} Prevention
- Double backslashes when embedding Windows-style paths in literals.
- Check that literals don't end with an odd number of backslashes.
- Use a shared escaping helper instead of manual string building.
When it happens
Trigger: Calling `read_quoted_text` on a quoted literal whose content ends with a trailing backslash, e.g. `"abc\` (quote opened, backslash consumed, then end of buffer).
Common situations: User-provided string literals (SQL values, JSON-ish text, config entries) with an unescaped trailing backslash from a Windows path (C:\), a truncated write, or an escaping pass that doubled up incorrectly.
Related errors
- Expected to have char
- Expected to have quotes in string literal.
- Expected to have terminated string literal after quota
- Expected to have terminated string literal after quota '…
- {e}
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/93743f371edb3ae9.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/io/src/cursor_ext/cursor_read_string_ext.rs:52
impl<T> BufferReadStringExt for Cursor<T>
where T: AsRef<[u8]>
{
fn read_quoted_text(&mut self, buf: &mut Vec<u8>, quote: u8) -> Result<()> {
self.must_ignore_byte(quote)?;
loop {
self.keep_read(buf, |b| b != quote && b != b'\\');
if self.ignore_byte(quote) {
if self.peek_byte() == Some(quote) {
buf.push(quote);
self.consume(1);
} else {
return Ok(());
}
} else if self.ignore_byte(b'\\') {
let b = Cursor::split(self).1;
if b.is_empty() {
return Err(std::io::Error::new(
ErrorKind::InvalidData,
"Expected to have terminated string literal after escaped char '\' ."
.to_string(),
));
}
let c = b[0];
self.ignore_byte(c);
match c {
b'n' => buf.push(b'\n'),
b't' => buf.push(b'\t'),
b'r' => buf.push(b'\r'),
b'0' => buf.push(b'\0'),
b'\'' => buf.push(b'\''),
b'\"' => buf.push(b'\"'),
b'\\' => buf.push(b'\\'),
b'/' => buf.push(b'/'),
_ => {View on GitHub (pinned to 288d84d76e)