vercel/next.js · error
Unterminated string
Error message
Unterminated string
What it means
Thrown by tokenizeArgs when the args string finishes with an odd number of double-quote characters, meaning a quoted value was opened but never closed. The tokenizer tracks isInString and rejects an unbalanced quote at end of input.
Source
Thrown at packages/next/src/server/lib/utils.ts:111
// If we find a quote, we should toggle the string flag.
else if (char === '"') {
isInString = !isInString
continue
}
// If we're starting a new argument, we should add it to the array.
if (willStartNewArg) {
args.push(char)
willStartNewArg = false
}
// Otherwise, add it to the last argument.
else {
args[args.length - 1] += char
}
}
if (isInString) {
throw new Error('Unterminated string')
}
return args
}
/**
* Get the node options from the environment variable `NODE_OPTIONS` and returns
* them as an array of strings.
*
* @returns An array of strings with the node options.
*/
export const getNodeOptionsArgs = () => {
if (!process.env.NODE_OPTIONS) return []
return tokenizeArgs(process.env.NODE_OPTIONS)
}
/**View on GitHub (pinned to 0ae8c72462)
Solutions
- Count the double-quotes in NODE_OPTIONS and ensure they are balanced (even count).
- Properly close every opened quote, e.g. change --title="app to --title="app".
- If the value has no spaces, remove the quotes entirely.
Example fix
# before: unclosed quote export NODE_OPTIONS='--title="my app' # after: balanced quotes export NODE_OPTIONS='--title="my app"'
Defensive patterns
Strategy: validation
Validate before calling
function hasBalancedQuotes(input: string): boolean {
return (input.match(/"/g) || []).length % 2 === 0
} Type guard
function hasBalancedQuotes(input: string): boolean {
return (input.match(/"/g) || []).length % 2 === 0
} Try / catch
try {
tokenizeArgs(process.env.NODE_OPTIONS || '')
} catch (e) {
if (e.message === 'Unterminated string') {
console.error('NODE_OPTIONS has an unbalanced quote')
process.exit(1)
}
} Prevention
- Ensure every opening quote in NODE_OPTIONS has a matching close.
- Count quotes when constructing NODE_OPTIONS in scripts.
- Drop quotes entirely for values without spaces.
When it happens
Trigger: NODE_OPTIONS contains a value with an opening quote but no closing quote, e.g. NODE_OPTIONS='--title="my app'. After the loop isInString is still true.
Common situations: Shell quoting mistakes in NODE_OPTIONS, a quote accidentally stripped by variable expansion, or copy-pasting a value that lost its closing quote.
Related errors
- Invalid escape character at the end.
- Unknown option: --${rawKey}
- Invalid --top value: ${topRaw}
- Invalid numeric value for --${key}: ${value}
- --routes cannot be empty
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/7b81bc981d23e2b7.
Report an issue: GitHub.