{"record":{"id":"e8ca23266de1ea1a","repo":"PRQL/prql","slug":"side-expected-inner-left-right-or-full-found","errorCode":null,"errorMessage":"`side`: expected inner, left, right or full, found {val}","messagePattern":"`side`: expected inner, left, right or full, found (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc/src/semantic/resolver/transforms.rs","lineNumber":116,"sourceCode":"                let [side, with, filter, tbl] = unpack::<4>(func.args);\n\n                let side = {\n                    let span = side.span;\n                    let ident = side.clone().try_cast(\n                        ExprKind::into_literal,\n                        Some(\"`side`\"),\n                        \"inner, left, right or full\",\n                    )?;\n\n                    // these must match the values of JoinSide defined in std.prql\n                    match ident.to_string().as_str() {\n                        \"\\\"inner\\\"\" => JoinSide::Inner,\n                        \"\\\"left\\\"\" => JoinSide::Left,\n                        \"\\\"right\\\"\" => JoinSide::Right,\n                        \"\\\"full\\\"\" => JoinSide::Full,\n\n                        val => {\n                            return Err(Error::new(Reason::Expected {\n                                who: Some(\"`side`\".to_string()),\n                                expected: \"inner, left, right or full\".to_string(),\n                                found: val.to_string(),\n                            })\n                            .with_span(span))\n                        }\n                    }\n                };\n\n                let filter = Box::new(filter);\n                let with = Box::new(with);\n                (TransformKind::Join { side, with, filter }, tbl)\n            }\n            \"group\" => {\n                let [by, pipeline, tbl] = unpack::<3>(func.args);\n\n                let by = Box::new(self.coerce_into_tuple(by)?);\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc/src/semantic/resolver/transforms.rs#L98-L134","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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\"`"],"exampleFix":"// before\nfrom employees\njoin side:outer salaries (==emp_id)\n// after\nfrom employees\njoin side:\"full\" salaries (==emp_id)","handlingStrategy":"validation","validationCode":"let side = \"full\";\nif (![\"inner\", \"left\", \"right\", \"full\"].includes(side)) {\n  throw new Error(`side must be one of inner/left/right/full, got ${side}`);\n}","typeGuard":"const isJoinSide = (v) => [\"inner\",\"left\",\"right\",\"full\"].includes(v);","tryCatchPattern":null,"preventionTips":["Always quote side values: side:\"left\"","Remember plain `join` is inner by default","Use `cross` transform for cross joins instead of a side value"],"tags":["prql","join","validation","query-language"],"backgroundTag":"invalid-enum-value","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"}