• Sound mode S-10, pre-alpha
  • Design record 0007, Accepted

TSR1003

Async function passed where '{0}' expects a function returning 'void'; its promise is never handled.

An async function is passed where a function returning void is expected, so its promise is never handled. Use a loop with await or Promise.all.

Rule S-10: No floating promises (level: strict). Reported by ts-r-check and ts-r-lsp in files that opt in to sound mode. See Sound mode.

What it means

An async function, or any function returning a promise, may not be passed where the parameter's type returns void: the callee ignores the returned promise, so rejections are lost. items.forEach(async ...) is the common case. It's reported at the function argument.

Example

Spec case from design record 0007 (checked by the record's case harness, not by this site's build)
// forEach ignores the promises its callback returns.
async function save(x: string): Promise<void> {
  console.log(x);
}
const items: string[] = ["a", "b"];
items.forEach(async (i) => { await save(i); }); // @expect TSR1003
export {};

How to fix

  • Use for...of with await inside an async function.
  • Or map to promises and wait for them: await Promise.all(items.map(async (i) => save(i))).
  • Or handle errors inside a non-async callback: items.forEach((i) => { save(i).catch(report); }).

Sound mode is defined in design record 0007 (accepted 2026-10-15).