cap_grant_exceeded: the program reaches a capability main was not granted
main’s capability parameters are the program’s grant: everything the program
can do, through any chain of calls, must fit inside it. This error points at a
use (a builtin call) that needs a capability outside the grant, and labels each
call on the way from main to it. A module’s needs line does not raise the
grant; it only declares what that module’s code may use.
A program that triggers it
mod Main do
needs IO.Console
needs IO.FileWrite
fn save(n : Int) : () do
let _ = file_write("/tmp/count", int_to_string(n))
()
end
fn main(_c : Cap(IO.Console)) do
save(1)
println("saved")
end
end
The fix
Grant main the capability too, by adding a parameter for it (or remove the
use):
mod Main do
needs IO.Console
needs IO.FileWrite
fn save(n : Int) : () do
let _ = file_write("/tmp/count", int_to_string(n))
()
end
fn main(_c : Cap(IO.Console), _fw : Cap(IO.FileWrite)) do
save(1)
println("saved")
end
end
Why the rule exists
The grant on main is what the person running the program agrees to. Reading
main’s signature tells them the most the program can do, so a program that
writes files must say so there, however deep the write is.
See also: the language reference.