Asyncwarnstrict preset

ai-guard/no-redundant-await

Detects redundant return await expressions outside try/catch blocks

What it does

Flags `return await value` inside async functions when the `await` is not inside a `try/catch/finally` block — where unwrapping the promise before returning is redundant.

Why AI tools generate this pattern

In an `async` function, `return somePromise` and `return await somePromise` are functionally equivalent *unless* the await is inside a `try/catch`. When outside a try/catch, both pass the promise through the async function's implicit wrapping, and the difference is invisible to callers. The extra `await` adds a microtask tick to the callstack with no benefit. AI tools add `return await` habitually — the pattern "feels safer" — but it's unnecessary overhead.

Code Examples

Incorrect (Flagged by AI Guard)
// redundant await — no try/catch surrounding it
async function fetchUser(id: string) {
  return await db.users.findOne(id); // ← await not needed here
}
Correct (Safe & Deterministic)
// No await needed when returning directly
async function fetchUser(id: string) {
  return db.users.findOne(id);
}

// await IS needed when inside try/catch (not flagged)
async function fetchUserSafe(id: string) {
  try {
    return await db.users.findOne(id); // ← needed: catch gets the rejection
  } catch (err) {
    return null;
  }
}

How to Fix

  1. Remove the `await` keyword from `return await expr` when it's not inside a try/catch/finally block.

Nuances & False Positive Prevention

Legitimate usage can be exempted with inline disable comments (// ai-guard-disable-next-line no-redundant-await) when appropriate.

Configuration

Enable or override this rule in your ESLint configuration:

eslint.config.mjs
// eslint.config.mjs
export default [
  {
    plugins: { 'ai-guard': aiGuard },
    rules: {
      'ai-guard/no-redundant-await': 'warn',
    },
  },
];

Related Rules