Rules / Complexity / avoid-redundant-async

avoid-redundant-async

lint/complexity/avoid-redundant-async
recommended
Same as avoid-redundant-async · Dart Code Metrics

Flags an async function whose body is a single return await ...;.

When a function does nothing with the awaited value but return it, the async/await round-trip is redundant: returning the Future directly is equivalent and skips an extra microtask hop and stack frame. The rule fires on a function or method marked async whose block body is exactly one statement of the form return await <expr>;.

Invalid

example.dartdart
// Bad: async with only one await and no error handling
Future<String> getName() async {
  return await db.getName();
}

Future<int> getValue() async {
  return await compute();
}

class Service {
  Future<User> getUser(String id) async {
    return await repository.fetchUser(id);
  }

  Future<List<String>> getNames() async {
    return await api.names();
  }
}

Future<dynamic> fetch(String url) async {
  return await http.get(url);
}

Future<String> transform(String input) async {
  return await processString(input);
}
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
1// Bad: async with only one await and no error handling
2Future<String> getName() async {
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
5
6Future<int> getValue() async {
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
10class Service {
11 Future<User> getUser(String id) async {
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
14
15 Future<List<String>> getNames() async {
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
19
20Future<dynamic> fetch(String url) async {
Unnecessary 'async' modifier — remove 'async' and 'await' to return the Future directly
23
24Future<String> transform(String input) async {

Valid

example.dartdart
// Good: removing unnecessary async/await
Future<String> getName() => db.getName();

Future<int> getValue() => compute();

class Service {
  Future<User> getUser(String id) => repository.fetchUser(id);

  Future<List<String>> getNames() => api.names();
}

Future<dynamic> fetch(String url) => http.get(url);

Future<String> transform(String input) => processString(input);

// OK: async with error handling
Future<String> safeGetName() async {
  try {
    return await db.getName();
  } catch (e) {
    return 'Default';
  }
}

// OK: async with multiple awaits
Future<User> buildUser(String id) async {
  final userData = await repository.fetchUser(id);
  final preferences = await repository.fetchPreferences(id);
  return User(userData, preferences);
}

// OK: async with additional logic
Future<String> processName() async {
  final name = await db.getName();
  print('Loaded: $name');
  return name.toUpperCase();
}

How to configure

Set the severity of avoid-redundant-async in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "avoid-redundant-async": "error"
      }
    }
  }
}