upstash/context7 · error · Error
Unterminated TOML literal string in MCP args
Error message
Unterminated TOML literal string in MCP args
What it means
A single-quoted (literal) TOML string in the args array was opened but no closing single quote exists anywhere after it in the file.
Source
Thrown at packages/cli/src/setup/toml-editor.ts:74
const width = escape === "u" ? 4 : 8;
const hex = source.slice(index, index + width);
if (!new RegExp(`^[0-9A-Fa-f]{${width}}$`).test(hex)) {
throw new Error(`Invalid TOML Unicode escape \\${escape}${hex}`);
}
const codePoint = Number.parseInt(hex, 16);
if (codePoint > 0x10ffff || (codePoint >= 0xd800 && codePoint <= 0xdfff)) {
throw new Error(`Invalid TOML Unicode code point U+${hex}`);
}
value += String.fromCodePoint(codePoint);
index += width;
}
throw new Error("Unterminated TOML basic string in MCP args");
}
function parseTomlLiteralString(source: string, start: number): TomlStringToken {
const endQuote = source.indexOf("'", start + 1);
if (endQuote === -1) throw new Error("Unterminated TOML literal string in MCP args");
const value = source.slice(start + 1, endQuote);
if (value.includes("\n") || value.includes("\r")) {
throw new Error("Multiline strings are not supported in MCP args");
}
return { value, start, end: endQuote + 1 };
}
function parseTomlStringArray(
source: string,
start: number
): { tokens: TomlStringToken[]; end: number } {
if (source[start] !== "[") throw new Error("Expected a TOML array for MCP args");
const tokens: TomlStringToken[] = [];
let index = start + 1;
while (index < source.length) {
index = skipTomlArrayTrivia(source, index);
if (source[index] === "]") return { tokens, end: index + 1 };View on GitHub (pinned to edc9eeb77b)
Solutions
- Add the closing single quote
- If the value contains an apostrophe, switch to a double-quoted basic string and escape as needed
- Check for smart quotes and replace with ASCII quotes
Example fix
// before args = ['--greeting 'hello'' // after args = ["--greeting 'hello'"]
Defensive patterns
Strategy: validation
Validate before calling
const idx = raw.indexOf("'");
// per line: literal strings must open and close on the same line
for (const line of raw.split('\n')) {
if (((line.match(/'/g) ?? []).length) % 2 !== 0) throw new Error('Unterminated literal string');
} Type guard
function literalStringClosed(line: string): boolean {
return (line.match(/'/g) ?? []).length % 2 === 0;
} Try / catch
catch (e) { if (/Unterminated TOML literal string/.test(e.message)) { /* close the string or switch to basic string */ } throw e; } Prevention
- Avoid literal strings for values containing apostrophes
- Pre-check file with a full TOML parser
When it happens
Trigger: args = ['--flag with no closing ', or the closing ' removed during editing; note literal strings cannot contain escapes so a stray ' inside the value ends the string early.
Common situations: Using a literal string for a value that itself contains an apostrophe (e.g. 'it's'); deleted closing quote; editor smart-quote substitution.
Related errors
- Unterminated TOML basic string in MCP args
- Multiline strings are not supported in MCP args
- Unsupported TOML escape \\${escape}
- Invalid TOML Unicode escape \\${escape}${hex}
- Invalid TOML Unicode code point U+${hex}
AI-assisted analysis of upstash/context7@edc9eeb77b (2026-08-28).
Data as JSON: /api/errors/2517f68d2028c59d.
Report an issue: GitHub.