PRQL/prql · error · Error
`side`: expected inner, left, right or full, found
Error message
`side`: expected inner, left, right or full, found {val} What it means
The PRQL compiler throws this when the `side` parameter of a `join` transform is not one of the four supported join kinds: inner, left, right, or full. The value is matched as a literal string (including quotes); anything else, including typos, unquoted identifiers, or wrong-case values, fails resolution. The error tells you exactly what was found so you can correct the `side:` argument.
Solutions
- Change the side value to one of "inner", "left", "right", or "full" (quoted strings)
- Note that plain `join` defaults to inner, so omit `side:` entirely if inner is intended
- For cross joins, use the `cross` transform instead of `join side:"cross"`
Example fix
// before from employees join side:outer salaries (==emp_id) // after from employees join side:"full" salaries (==emp_id)
Defensive patterns
Strategy: validation
Validate before calling
let side = "full";
if (!["inner", "left", "right", "full"].includes(side)) {
throw new Error(`side must be one of inner/left/right/full, got ${side}`);
} Type guard
const isJoinSide = (v) => ["inner","left","right","full"].includes(v);
Prevention
- Always quote side values: side:"left"
- Remember plain `join` is inner by default
- Use `cross` transform for cross joins instead of a side value
When it happens
Trigger: Calling `join side:<val> ...` with any side value other than the exact literals "inner", "left", "right", or "full" — e.g. `join side:inner` (unquoted), `side:"outer"`, `side:"Inner"`, `side:"cross"`, or a non-literal expression.
Common situations: Users coming from SQL write `outer` or `cross` instead of the PRQL-supported values; forgetting the quotes so the value is parsed as an identifier; using wrong capitalization after converting SQL queries.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- parameter `expanding`: expected a boolean, found
- parameter `rolling`: expected a number, found
- parameter `rows`: expected a range, found
- parameter `range`: expected a range, found
- {}
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/e8ca23266de1ea1a.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc/src/semantic/resolver/transforms.rs:116
let [side, with, filter, tbl] = unpack::<4>(func.args);
let side = {
let span = side.span;
let ident = side.clone().try_cast(
ExprKind::into_literal,
Some("`side`"),
"inner, left, right or full",
)?;
// these must match the values of JoinSide defined in std.prql
match ident.to_string().as_str() {
"\"inner\"" => JoinSide::Inner,
"\"left\"" => JoinSide::Left,
"\"right\"" => JoinSide::Right,
"\"full\"" => JoinSide::Full,
val => {
return Err(Error::new(Reason::Expected {
who: Some("`side`".to_string()),
expected: "inner, left, right or full".to_string(),
found: val.to_string(),
})
.with_span(span))
}
}
};
let filter = Box::new(filter);
let with = Box::new(with);
(TransformKind::Join { side, with, filter }, tbl)
}
"group" => {
let [by, pipeline, tbl] = unpack::<3>(func.args);
let by = Box::new(self.coerce_into_tuple(by)?);
View on GitHub (pinned to e164e249b9)