avoid_unrun_task
This rule flags a Task, TaskEither, IO, IOEither, TaskOption or IOOption that is evaluated as a statement and then discarded, without .run() ever being called on it.
Why use this rule
Section titled “Why use this rule”fpdart’s lazy types are descriptions of work, not the work itself. TaskEither.tryCatch(...) builds a plan; nothing executes until .run(). Dropping the value therefore does not merely waste a result — it skips the operation entirely. No request is sent, no row is written, no exception is thrown.
That silence is what makes this worse than a discarded Future, which at least ran. Here the program compiles, the types check, the test that mocks the repository still passes, and in production the save simply never happens.
This is the fpdart counterpart to the SDK’s unawaited_futures, and the one mistake in this family that the type system cannot catch on its own.
Either and Option are deliberately not reported: they are already-computed values, so discarding one wastes a result but never skips an effect.
See also: fpdart: Task, unawaited_futures
void save(User user) { repository.save(user); // returns TaskEither — never runs}Future<void> save(User user) async { await repository.save(user).run();}Returning it is equally fine — the caller then owns running it:
TaskEither<Failure, Unit> save(User user) => repository.save(user);Known limitations
Section titled “Known limitations”Only a discarded statement is reported. A value assigned to a variable is assumed to be run later, since the rule does not track what happens to it afterwards.
Options
Section titled “Options”many_lints: rules: avoid_unrun_task: additional_types: - LazyOperation ignore_cascades: truerules: avoid_unrun_task: additional_types: - LazyOperation ignore_cascades: true| Option | Type | Default | Description |
|---|---|---|---|
additional_types |
list of strings | [] |
Extra type names to treat as lazy, for projects that wrap fpdart’s types in their own |
ignore_cascades |
bool | false |
Skip a lazy value discarded as the target of a cascade |
Configuration
Section titled “Configuration”This rule is in the core preset, so it is on with preset: core,
preset: recommended or preset: opinionated.
To turn it off:
rules: avoid_unrun_task: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”prefer_task_either_over_try_catch— A repository’s failures belong in its signature, not in a try/catch.avoid_ad_hoc_left_type— A pipeline only composes when every step shares one error type.avoid_bare_await_in_do— Awaiting a raw Future inside a Do block escapes the block’s tracking.avoid_dollar_outside_do_frame— Calling a Do block’s extraction function from a nested callback unwinds through code that cannot handle it.