Reference · Files and processes

run_script

signature
run_script(str, map | null=) -> any

What it does

Runs Quillo code written by the program's users (a rule on a form's field, who may see a record) on the server, in a sandbox, and gives its last expression's value, or an error value saying what went wrong. The script sees the values in the map and Quillo's own builtins that only compute (len, upper, map, filter, date.parse, ...), never the program's functions of those names (since 0.7: a program's fn upper was the script's upper, run with the program's effects). It cannot read files, the environment or the database, define functions, routes or state, use files, or reply, and it gives back no function it made (since 0.7). It stops after 20,000 steps, and a value it makes may be up to 1 MB.

Examples

print(run_script("value > 3 ? null : `at least 4, got ${value}`", { value: 5 }))print(run_script("value > 3 ? null : `at least 4, got ${value}`", { value: 1 }))print(run_script("let total = items | map((i) => i.qty * i.price) | sum\ntotal > 100", { items: [{ qty: 2, price: 60 }] }))print(run_script("name.upper", { name: "ann" }))
output
nullat least 4, got 1trueANN

Edge cases

print(run_script("1 + 2"), run_script("1 + 2", null), run_script(""))print(run_script("env(\"HOME\")"), run_script("db.one(\"select 1\")"))print(run_script("date.parse(d)", { d: "2026-10-29" }), run_script("now()"))print(run_script("e(\"HOME\")", { e: env }))print(run_script("taken(\"a.txt\")", { taken: (p) => !is_err(read_file(p)) }))print(run_script("let i = 0\nwhile true { i = i + 1 }"))print(run_script("let s = \"x\"\nwhile true { s = s + s }"))print(run_script("return 5\n6"), run_script("f(2)", { f: (x) => x * 10 }))print(run_script("fn f() = 1\nf()"))print(run_script("route GET / = 1"), run_script("reply 400 \"no\""), run_script("<b>x</b>"))
output
3 3 nullerr("line 1: unknown name `env`") err("line 1: unknown name `db`")2026-10-29 err("line 1: unknown name `now`")err("line 1: `env` needs the env effect, which is not allowed here")falseerr("line 2: the script took too many steps")err("line 2: the script made a value larger than 1 MB")5 20err("a script cannot define functions (use `(x) => ...`)")err("a script cannot define routes") err("a script cannot reply") err("a script gives values, not markup")

A program's function of a builtin's name is not the script's, and what a script gives back is a value, not a function:

fn upper(s) = "the program's"print(run_script("upper(s)", { s: "ann" }), upper("ann"))print(run_script("(n) => n + 1"))
output
ANN the program'serr("a script gives back no function (it would run without the script's limits): give back what it computes")

Errors

Whatever goes wrong in the script, a parse error, an unknown name, a bad argument, division by zero, is an error value with the script's line, so the program can show it to the user; ?? default gives a value instead. The program's own mistakes are runtime errors: a source that is not a string, or values that are not a map.

let r = run_script("1 +")print(is_err(r), r.error)print(run_script("nope"), run_script("len(3)"), run_script("1 / 0"))print(run_script("err(\"bad\")") | is_err)print(run_script("nope") ?? false)
output
true line 1: expected an expression, found end of inputerr("line 1: unknown name `nope`") err("line 1: `len` expects a str, list or map, got int") err("line 1: division by zero")truefalse
this one fails
print(run_script("1", 2))
output
line 1: `run_script` expects a map as argument 2, got int

Chaining

The source comes first in a pipeline, the values in the call:

let rule = "age >= 18"print(rule | run_script({ age: 20 }), rule | run_script({ age: 12 }))print([{ age: 20 }, { age: 12 }] | filter((p) => run_script(rule, p)))
output
true false[{ age: 20 }]

See also

check_program, is_err, err, read_upload

Thread
7Useful? Like it, or add to its thread below.

Thread 0 posts

On run_script(): questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo