{"record":{"id":"ef5f7b1429070a7d","repo":"PRQL/prql","slug":"expected-expected-str-but-didn-t-find-anything","errorCode":null,"errorMessage":"Expected {expected_str}, but didn't find anything before the end.","messagePattern":"Expected (.+?), but didn't find anything before the end\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc-parser/src/parser/perror.rs","lineNumber":72,"sourceCode":"                let mut expected_strs = expected_strs;\n                expected_strs.sort();\n\n                let expected_str = match expected_strs.len() {\n                    1 => expected_strs[0].clone(),\n                    2 => expected_strs.join(\" or \"),\n                    _ => {\n                        let last = expected_strs.pop().unwrap();\n                        format!(\"one of {} or {last}\", expected_strs.join(\", \"))\n                    }\n                };\n\n                match found {\n                    Some(_) => Error::new(Reason::Expected {\n                        who: None,\n                        expected: expected_str,\n                        found: found_str,\n                    }),\n                    None => Error::new(Reason::Simple(format!(\n                        \"Expected {expected_str}, but didn't find anything before the end.\"\n                    ))),\n                }\n            }\n        }\n        RichReason::Custom(msg) => Error::new_simple(msg.to_string()),\n    };\n\n    error.with_span(Some(span))\n}\n\nimpl<'a> From<Rich<'a, crate::lexer::lr::Token, Span>> for Error {\n    fn from(rich: Rich<'a, crate::lexer::lr::Token, Span>) -> Error {\n        rich_error_to_error(\n            *rich.span(),\n            rich.reason(),\n            |token| format!(\"{}\", token.kind),\n            |token| matches!(token.kind, TokenKind::NewLine | TokenKind::Start),","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc-parser/src/parser/perror.rs#L54-L90","documentation":"When the parser expected a construct but reached end-of-input, `rich_error_to_error` builds a `Reason::Simple` with this message instead of `Expected X, found Y`. It means the query ended abruptly in the middle of a construct.","triggerScenarios":"Truncated input: unclosed parenthesis/bracket, dangling pipe at end of file, incomplete function definition, or empty argument at EOF passed to the parser.","commonSituations":"File cut off during save; heredoc/stdin piping lost trailing lines; half-typed query in watch mode; copy-paste that dropped the last line.","solutions":["Complete the unfinished expression or close the open bracket at the reported location","Check the file/stdin wasn't truncated (compare against source)","Avoid a trailing `|` with nothing after it"],"exampleFix":"// before\nfrom employees | filter\n// after\nfrom employees | filter age > 30","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { compile(prql) } catch (e) { if (String(e).includes(\"didn't find anything before the end\")) { checkUnbalancedBrackets(prql) } else { throw e } }","preventionTips":["Balance-check parentheses/brackets before compiling","Verify piped files/heredocs are not truncated","Avoid trailing pipes with no following transform"],"tags":["parser","syntax-error","unexpected-eof"],"backgroundTag":"invalid-argument-format","analyzedSha":"e164e249b99485890036eb60f57c37520379b240","analyzedAt":"2026-09-09T12:18:38.727Z","contentChangedAt":"2026-09-09T12:18:38.727Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}