Unsafe task usage detection.
Detects two patterns that commonly cause production issues:
Leaked async tasks —
Task.asyncorTask.Supervisor.async_nolinkcalls in functions that never await/yield the result, directly or transitively through the call graph.Unchecked start_child —
Task.Supervisor.start_childcalls where the result is discarded without error handling. The call is not in tail position and no branch instruction follows it, indicating the{:ok, pid}/{:error, reason}result is ignored.
Suppresses leaked_async_task for process modules with message-receiving
callbacks (GenServer, LiveView, LiveComponent, gen_statem) that consume
task results through their mailbox rather than explicit await/yield.
Also recognizes Task.shutdown/1,2 as a valid way to consume a task.
Requires the OTP extractor for implements_behaviour facts.
Output relations
leaked_async_task(func, id)— async task created but never awaited.unchecked_start_child(func, id)— start_child result not checked.
Finding severities
Both relations are :warning: leaked tasks crash their caller or pile
up unread result messages; unchecked starts make failed launches look
like success. Neither is a guaranteed failure on every execution.