PRQL/prql · error · Error
Unexpected ` ` (this is probably a 'bad type' error)
Error message
Unexpected `{found}` (this is probably a 'bad type' error) What it means
The lowering phase only handles expressions that the resolver has already type-checked and flattened into simple constructs. If it still encounters a `FuncCall`, `Func`, or `TransformCall`, it means a function or transform survived into lowering, which indicates a prior type error (the compiler says it is 'probably a bad type error').
Solutions
- Check that functions are actually called with arguments, not referenced as values
- Verify the argument types of your custom functions (a 'bad type' upstream likely caused this)
- Look for transforms (`filter`, `select`, etc.) used outside pipeline position
- Reformulate the expression so functions/transforms appear only in pipeline contexts
Example fix
// before select my_func // after select my_func col
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure every function reference is invoked (has call args)
for (const fn of customFunctions) {
if (!query.includes(fn.name + " ") && !query.includes(fn.name + "(")) {
console.warn(`function ${fn.name} may be used as a value`);
}
} Type guard
function isCalledFunction(node) {
return node.kind === "func_call" || node.kind === "func";
} Try / catch
try {
compile(query);
} catch (e) {
if (e.message.includes("'bad type' error")) {
console.error("Check function argument types; a function/transform leaked into value position:", e.message);
} else { throw e; }
} Prevention
- Always call functions with arguments; never reference them as values
- Annotate custom function parameter types so inference fails earlier with better errors
- Keep transforms (filter/select) only in pipeline position
When it happens
Trigger: Calling a function in a position whose expected type does not invoke/lower it, e.g. a function used as a value `select my_func` (without call) or a transform like `filter` used as a value, or a user-defined function whose argument type inference failed.
Common situations: Forgetting to call a function (missing parentheses/arguments), passing a transform where a column is expected, or a type annotation mismatch that left the function unresolved.
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
- expected a pipeline that resolves to a table, found
- expected an identifier, found
- {}
- Currently `lex` only works with a single source, but found…
- Currently `annotate` only works with a single source, but…
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/af3b84dfeeac2ebb.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc/src/semantic/lowering.rs:977
pl::ExprKind::Tuple(_) => {
return Err(
Error::new_simple("table instance cannot be referenced directly")
.push_hint("column name might be missing?")
.with_span(span),
);
}
pl::ExprKind::Array(exprs) => rq::ExprKind::Array(
exprs
.into_iter()
.map(|x| self.lower_expr(x))
.try_collect()?,
),
pl::ExprKind::FuncCall(_) | pl::ExprKind::Func(_) | pl::ExprKind::TransformCall(_) => {
log::debug!("cannot lower {expr:?}");
return Err(Error::new(Reason::Unexpected {
found: format!("`{}`", write_pl(expr.clone())),
})
.push_hint("this is probably a 'bad type' error (we are working on that)")
.with_span(expr.span));
}
pl::ExprKind::Internal(_) => {
return Err(Error::new_assert(format!(
"Unresolved lowering: {}",
write_pl(expr)
)))
}
};
Ok(rq::Expr { kind, span })
}
fn lower_interpolations(View on GitHub (pinned to e164e249b9)