PRQL/prql · error

Currently `lex` only works with a single source, but found…

Error message

Currently `lex` only works with a single source, but found multiple sources

What it means

The `prqlc lex` CLI command lexes a PRQL source into tokens, but the lexer input model assumes a single source file. When the command receives multiple sources (e.g. main query plus includes via --include or stdin+files), execute() bails with this anyhow error instead of lexing each in turn.

Solutions

  1. Run lex on exactly one .prql file at a time
  2. Remove --include arguments (or merge includes into one file temporarily) before lexing
  3. Use `prqlc format` or `prqlc compile` (which do handle multiple sources) if multi-file processing is needed
  4. Split a project into per-file lex invocations in your script

Example fix

# before
prqlc lex main.prql --include helpers.prql
# after
prqlc lex main.prql
Defensive patterns

Strategy: validation

Validate before calling

# Ensure a single input before lexing
if [ "$(ls *.prql | wc -l)" -ne 1 ]; then echo "pass exactly one file"; exit 1; fi
prqlc lex main.prql

Try / catch

# Shell guard
prqlc lex "$1" || echo "lex failed: pass exactly one source file"

Prevention

When it happens

Trigger: Running `prqlc lex` with more than one source — multiple input files, a main file plus --include files, or a project directory resolved to several sources.

Common situations: Pointing lex at a project dir containing stdlib/includes; passing several .prql files on the command line; CI scripts feeding both a file and stdin.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09). Data as JSON: /api/errors/c3c87507773392fa. Report an issue: GitHub.

Appendix: source

Thrown at prqlc/prqlc/src/cli/mod.rs:414

    fn execute<'a>(&self, sources: &'a mut SourceTree, main_path: &'a str) -> Result<Vec<u8>> {
        let main_path = main_path
            .split('.')
            .filter(|x| !x.is_empty())
            .map(str::to_string)
            .collect_vec();

        Ok(match self {
            Command::Parse { format, .. } => {
                let ast = prql_to_pl_tree(sources)?;
                match format {
                    Format::Json => serde_json::to_string_pretty(&ast)?.into_bytes(),
                    Format::Yaml => serde_yaml::to_string(&ast)?.into_bytes(),
                }
            }
            Command::Lex { format, .. } => {
                let s = sources.sources.values().exactly_one().or_else(|_| {
                    // TODO: allow multiple sources
                    bail!("Currently `lex` only works with a single source, but found multiple sources")
                })?;
                let tokens = prql_to_tokens(s)?;
                match format {
                    Format::Json => serde_json::to_string_pretty(&tokens)?.into_bytes(),
                    Format::Yaml => serde_yaml::to_string(&tokens)?.into_bytes(),
                }
            }
            Command::Collect(_) => {
                let mut root_module_def = prql_to_pl_tree(sources)?;

                drop_module_def(&mut root_module_def.stmts, "std");

                pl_to_prql(&root_module_def)?.into_bytes()
            }
            Command::Debug(DebugCommand::Annotate(_)) => {
                let (_, source) = sources.sources.clone().into_iter().exactly_one().or_else(
                    |_| bail!(
                        "Currently `annotate` only works with a single source, but found multiple sources: {:?}",

View on GitHub (pinned to e164e249b9)