Effect inference

How the compiler validates effects

The compiler checks effects transitively. When you call a function with needs { net }, your function must also declare needs { net } (or a superset).

cleat
fn inner() -> string needs { net } { ... }
fn outer() -> string needs { net } {  // must declare net
    return inner()
}

Calling inner() from a function without needs { net } is a compile error.

Error messages

The compiler produces clear diagnostics:

text
error: missing needs effect: net
  --> main.cleat:4:12
   |
 4 |     return http.get("https://example.com")
   |            ^

Levenshtein suggestions

Misspelled effect names get correction suggestions:

text
error: unknown effect "nett" in fn greet
  --> main.cleat:1:27
   |
 1 | fn greet() -> int needs { nett } {
   |                           ^^^^
   = help: did you mean "net"?

Agent effect coverage

Agent declarations must cover all their tools' effects:

cleat
tool search(q: string) -> Result[string, string]
    needs { net }
    timeout: 10s
{ ... }

agent Bot {
    model: "claude-sonnet-4-20250514"
    system: "Search bot."
    tool: [search]
    needs { llm }        // ← compile error: missing effect "net" required by tool "search"
    // needs { llm, net }  // correct
}

Server effect coverage

Server declarations must cover all their handlers' effects:

cleat
fn handler(req: server.Request) -> Result[server.Response, string] needs { llm } { ... }

server API {
    addr: ":8080"
    needs { net }        // ← error: handler requires effect "llm" not declared by server
    // needs { net, llm }  // correct
    get "/api" = handler
}
Edit this page on GitHub