PRQL/prql · error · Error

expected a pipeline that resolves to a table, found

Error message

expected a pipeline that resolves to a table, found `{found_str}`

What it means

During lowering (semantic IR to SQL IR), PRQL expects the function-call argument or pipeline fed to a relational context (e.g. `from x | ...` used as a value) to resolve to a table. If the expression instead lowers to a non-table value (a scalar, column, or unlowered expression), the compiler throws this error and then tries to attach hints for common mistakes.

Solutions

  1. Ensure the expression is a full pipeline that ends in a table (e.g. `from employees`) rather than a scalar or column expression
  2. If you intended a scalar comparison, move the pipeline out of the scalar context or use `first`/aggregate to reduce it to a value
  3. Check the found expression in the error message; correct typos or missing `from` clauses
  4. See the attached hint (the compiler adds hints for common mistakes such as missing `from`)

Example fix

// before
select (employees)
// after
from employees | select name
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the expression is a pipeline starting with from
// e.g. reject scalars/strings passed as sources
if (!query.trim().startsWith("from ")) {
  throw new Error("pipeline must start with `from <table>`");
}

Type guard

function isTablePipeline(expr) {
  return typeof expr === "string" && /(^|\|)\s*from\s+\w+/.test(expr);
}

Try / catch

try {
  compile(query);
} catch (e) {
  if (e.message.includes("a pipeline that resolves to a table")) {
    console.error("Add a `from <table>` clause; subqueries need a full pipeline:", e.message);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Passing a non-table expression where a relation is required, e.g. `select (from employees)` (subquery in scalar position), `join`ing against a scalar, or feeding a column expression where a pipeline resolving to a table is expected.

Common situations: Writing an inline subquery without the std-style pattern, mistyping a table name so it resolves to something else, or using a scalar function result as a pipeline source.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at prqlc/prqlc/src/semantic/lowering.rs:431

                log::debug!("lowering literal relation table, columns = {columns:?}");
                let relation = rq::Relation {
                    kind: rq::RelationKind::Literal(lit),
                    columns,
                };

                self.table_buffer.push(TableDecl {
                    id: tid,
                    name: None,
                    relation,
                });

                // return an instance of this new table
                self.create_a_table_instance(id, None, tid)
            }

            _ => {
                let found_str = write_pl(expr.clone());
                let mut error = Error::new(Reason::Expected {
                    who: None,
                    expected: "a pipeline that resolves to a table".to_string(),
                    found: format!("`{}`", found_str),
                });

                // Provide better hints for common mistakes
                if found_str.starts_with("internal std.sub") {
                    // This is likely a negative number or expression that should be wrapped in parentheses
                    error = error.push_hint(
                        "wrap negative numbers in parentheses, e.g. `sort (-column_name)`",
                    );
                } else {
                    error = error.push_hint("`from` statement might be missing?");
                }

                return Err(error.with_span(expr.span));
            }
        })

View on GitHub (pinned to e164e249b9)