{"record":{"id":"609f482084ebcd29","repo":"evanw/esbuild","slug":"unterminated-string-literal","errorCode":null,"errorMessage":"Unterminated string literal","messagePattern":"Unterminated string literal","errorType":"panic","errorClass":"LexerPanic","httpStatus":null,"severity":"error","filePath":"internal/js_lexer/js_lexer.go","lineNumber":1483,"sourceCode":"\t\tstringLiteral:\n\t\t\tfor {\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tneedsSlowPath = true\n\t\t\t\t\tlexer.step()\n\n\t\t\t\t\t// Handle Windows CRLF\n\t\t\t\t\tif lexer.codePoint == '\\r' && lexer.json != JSON {\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tif lexer.codePoint == '\\n' {\n\t\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\tpanic(LexerPanic{})\n\n\t\t\t\tcase '\\r':\n\t\t\t\t\tif quote != '`' {\n\t\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\t\tpanic(LexerPanic{})\n\t\t\t\t\t}\n\n\t\t\t\t\t// Template literals require newline normalization\n\t\t\t\t\tneedsSlowPath = true\n\n\t\t\t\tcase '\\n':\n\t\t\t\t\tif quote != '`' {\n\t\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\t\tpanic(LexerPanic{})\n\t\t\t\t\t}\n\n\t\t\t\tcase '$':\n\t\t\t\t\tif quote == '`' {","sourceCodeStart":1465,"sourceCodeEnd":1501,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/js_lexer/js_lexer.go#L1465-L1501","documentation":"This is a JavaScript/TypeScript lexer error indicating that a string literal (single-quote, double-quote, or template literal) was not properly terminated before the lexer reached the end of file (code point -1) or, for non-template strings, a bare newline character. The error is added as a RangeError and the lexer panics with LexerPanic to abort parsing.","triggerScenarios":"A source file contains an unclosed string literal such as const x = \"hello at the end of the file without a closing quote, or a single/double-quoted string that contains a raw newline character (not allowed in JS/TS).","commonSituations":"Missing closing quote due to a typo, a string accidentally spanning a newline in non-template-literal context, an escaped character that was meant to include the closing quote, or corrupted/truncated source files.","solutions":["Add the missing closing quote character (' or \" or `) to terminate the string","For multi-line strings, use a backtick template literal or concatenate with '+'","Check for stray newline characters inside the string by examining the source around the error location","If the file appears truncated, verify the file is complete and not cut off"],"exampleFix":"// before\nconst greeting = \"hello world;\n// after\nconst greeting = \"hello world\";","handlingStrategy":"validation","validationCode":"// Pre-validate source files for unterminated string literals\nfunction checkUnterminatedStrings(source) {\n  for (let i = 0; i < source.length; i++) {\n    const ch = source[i]\n    if (ch === '\"' || ch === \"'\") {\n      // scan forward for closing quote\n      let j = i + 1\n      while (j < source.length && source[j] !== ch) {\n        if (source[j] === '\\\\') j++ // skip escaped char\n        if (source[j] === '\\n' || source[j] === '\\r') {\n          return { unterminated: true, line: source.substring(0, i).split('\\n').length }\n        }\n        j++\n      }\n      if (j >= source.length) {\n        return { unterminated: true, line: source.substring(0, i).split('\\n').length }\n      }\n      i = j\n    }\n  }\n  return { unterminated: false }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await esbuild.transform(source, { loader: 'ts' })\n} catch (e) {\n  if (e.message?.includes('Unterminated string literal')) {\n    const loc = e.errors?.[0]?.location\n    console.error(`Syntax error at ${loc?.file}:${loc?.line}:${loc?.column}: add the missing quote`)\n  }\n  throw e\n}","preventionTips":["Use a code editor with syntax highlighting to catch unclosed strings","Run a linter (ESLint, Biome) before bundling to catch syntax errors","For multi-line strings, use template literals (backticks) instead of quotes","Check for stray newlines or missing escape characters in string content"],"tags":["esbuild","lexer","javascript","typescript","syntax","string"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}