commaai/openpilot · warning · ValueError
Function body is empty
Error message
Function body is empty
What it means
jotpluggler's math_eval evaluates user code from the per-metric code file. _evaluate_user_code() strips whitespace and refuses an empty body - there is literally nothing to eval or wrap in a generated function. This is a fast, clear validation failure before exec/eval machinery runs.
Source
Thrown at openpilot/tools/jotpluggler/math_eval.py:38
def _write_vector(path: str, values: np.ndarray) -> None:
np.asarray(values, dtype=np.float64).tofile(path)
def _resample_to_reference(ref_t: np.ndarray, src_t: np.ndarray, src_v: np.ndarray) -> np.ndarray:
ref_t = np.asarray(ref_t, dtype=np.float64).reshape(-1)
src_t = np.asarray(src_t, dtype=np.float64).reshape(-1)
src_v = np.asarray(src_v, dtype=np.float64).reshape(-1)
if ref_t.size == 0 or src_t.size == 0 or src_v.size == 0:
return np.empty_like(ref_t)
indices = np.searchsorted(src_t, ref_t, side="right") - 1
indices = np.clip(indices, 0, src_v.size - 1)
return src_v[indices]
def _evaluate_user_code(code: str, env: dict):
stripped = code.strip()
if not stripped:
raise ValueError("Function body is empty")
expr = stripped
if expr.startswith("return "):
expr = expr[7:].strip()
try:
return eval(expr, env, env)
except SyntaxError:
pass
function_src = "def __jotpluggler_eval__():\n" + textwrap.indent(code, " ")
exec(function_src, env, env)
return env["__jotpluggler_eval__"]()
def main() -> int:
if len(sys.argv) != 6:
print("usage: math_eval.py <manifest.json> <globals.py> <code.py> <out_t.bin> <out_v.bin>", file=sys.stderr)
return 2View on GitHub (pinned to 516ec1e682)
Solutions
- Put an expression or a function body into the code file, e.g. 'return a * 2' or a bare expression using env variables
- Check the file actually being read (code_path) - it may not be the file you edited
- If the metric is intentionally unused, remove its config entry instead of leaving an empty code file
Example fix
# before (code file contents) # after return src_v * 3.28084 # m/s to ft/s
Defensive patterns
Strategy: validation
Validate before calling
code = open(code_path, encoding='utf-8').read()
if not code.strip():
raise SystemExit(f"metric code file {code_path} is empty - write an expression or remove the metric") Try / catch
try:
result = _evaluate_user_code(user_code, env)
except ValueError as e:
if 'empty' in str(e):
raise SystemExit(f'fill in or delete {code_path}')
raise Prevention
- Reject empty code files at metric-creation time (in scaffolding/tooling), not at eval time
- Add a trivial smoke test per metric (eval once with sample env) to CI so blank templates fail early
When it happens
Trigger: A metric's code file is empty or contains only whitespace/newlines; template metric created but never filled in; file path resolution returned an empty file.
Common situations: Scaffolding a new custom series and forgetting to write the expression; editor saved an empty buffer; CI fixture generating blank code files.
Related errors
- No reference series found. Set an input timeseries or return
- Custom series returned an empty result
- invalid config backup: {backup}
- No camera file for segment {seg_idx}
- No valid camera paths
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/5947c04e3b628eae.
Report an issue: GitHub.