{"record":{"id":"f706843fecf09f83","repo":"PRQL/prql","slug":"expected-a-table-found-found-desc","errorCode":null,"errorMessage":"expected a table, found {found_desc}","messagePattern":"expected a table, found (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc/src/semantic/resolver/types.rs","lineNumber":111,"sourceCode":"            return Ok(());\n        };\n\n        let Some(found_ty) = &mut found.ty else {\n            // found is none: infer from expected\n\n            if found.lineage.is_none() && expected.unwrap().is_relation() {\n                // special case: infer a table type\n                // inferred tables are needed for s-strings that represent tables\n                // similarly as normal table references, we want to be able to infer columns\n                // of this table, which means it needs to be defined somewhere\n                // in the module structure.\n                let Some(id) = found.id else {\n                    // Expression has no id - this happens with bare lambdas like `x -> y`\n                    let found_desc = match &found.kind {\n                        ExprKind::Func(_) => \"a function\".to_string(),\n                        kind => format!(\"{kind:?}\"),\n                    };\n                    return Err(Error::new(Reason::Expected {\n                        who: None,\n                        expected: \"a table\".to_string(),\n                        found: found_desc,\n                    })\n                    .with_span(found.span));\n                };\n\n                let frame = self.declare_table_for_literal(id, None, found.alias.clone());\n\n                // override the empty frame with frame of the new table\n                found.lineage = Some(frame)\n            }\n\n            // base case: infer expected type\n            found.ty = expected.cloned();\n\n            return Ok(());\n        };","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc/src/semantic/resolver/types.rs#L93-L129","documentation":"A pipeline stage that requires a table (e.g. `from`) was given an expression that is not a table. When the found expression has no relation id — for instance a bare lambda like `x -> y` or a plain function — the resolver reports what kind of thing it actually found instead of 'a table'.","triggerScenarios":"Writing `from (x -> y)` (bare lambda), `from some_function`, or piping a function/literal into a transform that expects a relation rather than a table-typed expression.","commonSituations":"Confusing functions/lambdas with relations, forgetting to call a function that returns a table, or passing a scalar expression where a table is required.","solutions":["Call the function if it returns a table: `from (my_func arg)` rather than `from my_func`.","Replace the lambda/function with an actual table reference, e.g. `from employees`.","Check the expression's type: it must be a relation/table to sit in a `from` position."],"exampleFix":"// before\nfrom (x -> x)\n// after\nfrom employees","handlingStrategy":"type-guard","validationCode":"// ensure the argument is a table reference before putting it in `from`\nif (typeof source !== 'string' && !isTableCall(source)) throw new Error('from requires a table');","typeGuard":"const isTableRef = (e) => typeof e === 'string' || (e.kind === 'ident' && !e.isLambda && !e.isFunc);","tryCatchPattern":"try { compile(prql) } catch (e) { if (e.message.includes('expected a table')) { /* replace the expression with a table or call the function */ } }","preventionTips":["Only place table-typed expressions after `from` or as relation arguments","Call table-returning functions with parentheses instead of passing them bare","Don't use bare lambdas in pipeline source positions"],"tags":["prql","compile-time","type-mismatch","table"],"backgroundTag":"type-mismatch","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"}