{"record":{"id":"5191731393ce2228","repo":"apple/pkl","slug":"stringcontentmustbeginonnewline","errorCode":"stringContentMustBeginOnNewLine","errorMessage":"The content of a multi-line string must begin on a new line.","messagePattern":"The content of a multi-line string must begin on a new line\\.","errorType":"error_code","errorClass":"ParserError","httpStatus":null,"severity":"error","filePath":"pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java","lineNumber":1200,"sourceCode":"        case EOF -> {\n          var delimiter = new StringBuilder(start.text(lexer)).reverse().toString();\n          throw parserError(\"missingDelimiter\", delimiter);\n        }\n      }\n    }\n    var end = next().span;\n    var fullSpan = start.span.endWith(end);\n    var parts = validateMultiLineString(stringTokens, fullSpan);\n    return new MultiLineStringLiteralExpr(parts, start.span, end, fullSpan);\n  }\n\n  private List<StringPart> validateMultiLineString(List<TempNode> nodes, Span span) {\n    var firstNode = nodes.isEmpty() ? null : nodes.get(0);\n    if (firstNode == null\n        || firstNode.token == null\n        || firstNode.token.token != Token.STRING_NEWLINE) {\n      var errorSpan = firstNode == null ? span : firstNode.span();\n      throw new ParserError(ErrorMessages.create(\"stringContentMustBeginOnNewLine\"), errorSpan);\n    }\n    // only contains a newline\n    if (nodes.size() == 1) {\n      return List.of(new StringChars(\"\", firstNode.span()));\n    }\n    var indent = getCommonIndent(nodes, span);\n    return renderString(nodes, indent);\n  }\n\n  private List<StringPart> renderString(List<TempNode> nodes, String commonIndent) {\n    var parts = new ArrayList<StringPart>();\n    var builder = new StringBuilder();\n    var lastToken = nodes.get(nodes.size() - 1).token;\n    assert lastToken != null;\n    var endOffset = lastToken.token == Token.STRING_NEWLINE ? 1 : 2;\n    var isNewLine = true;\n    Span start = null;\n    Span end = null;","sourceCodeStart":1182,"sourceCodeEnd":1218,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java#L1182-L1218","documentation":"In a Pkl multi-line string (\"\"\"...\"\"\"), the content is required to start on its own line after the opening delimiter. The parser validates the parsed string nodes and throws when the very first node is not a newline token, i.e. content immediately follows the opening triple quote. This rule keeps multi-line strings free of the opening delimiter's indentation.","triggerScenarios":"Parsing source where a multi-line string is opened like `text: \"\"\"hello` with content on the same line as the opening `\"\"\"`, or where the string is empty/malformed such that no STRING_NEWLINE token starts the content list.","commonSituations":"Developers used to Kotlin/Scala raw strings writing `\"\"\"text` on one line; converting YAML or heredocs to Pkl; editor snippets that collapse the newline after the opening delimiter.","solutions":["Put a line break immediately after the opening `\"\"\"` delimiter so content starts on the next line","Indent the string content; Pkl strips the common indentation automatically","If a single-line value was intended, use a normal quoted string instead of a multi-line one"],"exampleFix":"// before\nmsg: \"\"\"hello\n// after\nmsg: \"\"\"\n  hello\n  \"\"\"","handlingStrategy":"validation","validationCode":"function multilineStringOpensOnNewLine(line) {\n  const m = line.match(/\"\"\"(.*)$/);\n  return !(m && m[1].trim() !== ''); // true if opening \"\"\" is alone on its line\n}\n// scan each line of the .pkl source containing '\"\"\"' before parsing","typeGuard":"null","tryCatchPattern":"try {\n  const result = parser.parse(source);\n} catch (e) {\n  if (e.errorId === 'stringContentMustBeginOnNewLine') {\n    // suggest inserting a newline after the opening triple quote at e.span\n  } else { throw e; }\n}","preventionTips":["Always put content on the line after the opening \"\"\"","Use a Pkl formatter/IDE plugin for multi-line strings","Prefer single-quoted strings for one-line values"],"tags":["parser","pkl","multi-line-string","syntax-error"],"backgroundTag":"multiline-string-format-error","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}