Environment information
CLI:
Version: 2.3.9
Color support: true
Platform:
CPU Architecture: aarch64
OS: macos
Environment:
BIOME_LOG_PATH: unset
BIOME_LOG_PREFIX_NAME: unset
BIOME_CONFIG_PATH: unset
BIOME_THREADS: unset
NO_COLOR: unset
TERM: xterm-256color
JS_RUNTIME_VERSION: v25.2.1
JS_RUNTIME_NAME: node
NODE_PACKAGE_MANAGER: bun/1.3.5
Biome Configuration:
Status: Loaded successfully
Path: biome.json
Formatter enabled: true
Linter enabled: true
Assist enabled: true
VCS enabled: true
HTML full support enabled: unset
Workspace:
Open Documents: 0
What happened?
Consider the following code:
async function* plus(iterable: AsyncIterable<number>, n: number) {
for await (const v of iterable) {
yield v + n;
}
}
function* plusThreeEverythingAndThenPlusTwoEverything(
iterable: AsyncIterable<number>,
) {
yield* plus(iterable, 3);
yield* plus(iterable, 2);
}
https://biomejs.dev/playground/?code=YQBzAHkAbgBjACAAZgB1AG4AYwB0AGkAbwBuACoAIABwAGwAdQBzACgAaQB0AGUAcgBhAGIAbABlADoAIABBAHMAeQBuAGMASQB0AGUAcgBhAGIAbABlADwAbgB1AG0AYgBlAHIAPgAsACAAbgA6ACAAbgB1AG0AYgBlAHIAKQAgAHsACgAgACAAZgBvAHIAIABhAHcAYQBpAHQAIAAoAGMAbwBuAHMAdAAgAHYAIABvAGYAIABpAHQAZQByAGEAYgBsAGUAKQAgAHsACgAgACAAIAAgAHkAaQBlAGwAZAAgAHYAIAArACAAbgA7AAoAIAAgAH0ACgB9AAoACgBmAHUAbgBjAHQAaQBvAG4AKgAgAHAAbAB1AHMAVABoAHIAZQBlAEUAdgBlAHIAeQB0AGgAaQBuAGcAQQBuAGQAVABoAGUAbgBQAGwAdQBzAFQAdwBvAEUAdgBlAHIAeQB0AGgAaQBuAGcAKAAKACAAIABpAHQAZQByAGEAYgBsAGUAOgAgAEEAcwB5AG4AYwBJAHQAZQByAGEAYgBsAGUAPABuAHUAbQBiAGUAcgA%2BACwACgApACAAewAKACAAIAB5AGkAZQBsAGQAKgAgAHAAbAB1AHMAKABpAHQAZQByAGEAYgBsAGUALAAgADMAKQA7AAoAIAAgAHkAaQBlAGwAZAAqACAAcABsAHUAcwAoAGkAdABlAHIAYQBiAGwAZQAsACAAMgApADsACgB9AAoA
EDIT: the code above is a bit silly because the second plus(…) call doesn't do anything — the iterator is already consumed. See below for an example that can't be trivially rewritten.
Biome errors and tells me that the async keyword is unnecessary:
Remove this async modifier, or add an await expression in the function. Async functions without await expressions may not need to be declared async.
However, removing the async would cause the code to break, because we are yielding to an async iterable.
Expected result
No error.
I'm not sure exactly what the best course of action here is. The simplest would be to count yield* similar to an await call in an async function — that's probably what I would do to eliminate false positives. But yield* … can also be used to yield to sync generators (even from inside async functions), so this would allow false negatives.1
However, the code is concise and idiomatic for combinators of iterables. It doesn't feel right to rewrite it or to add a permanent comment for Biome to ignore it.
Code of Conduct
Environment information
What happened?
Consider the following code:
https://biomejs.dev/playground/?code=YQBzAHkAbgBjACAAZgB1AG4AYwB0AGkAbwBuACoAIABwAGwAdQBzACgAaQB0AGUAcgBhAGIAbABlADoAIABBAHMAeQBuAGMASQB0AGUAcgBhAGIAbABlADwAbgB1AG0AYgBlAHIAPgAsACAAbgA6ACAAbgB1AG0AYgBlAHIAKQAgAHsACgAgACAAZgBvAHIAIABhAHcAYQBpAHQAIAAoAGMAbwBuAHMAdAAgAHYAIABvAGYAIABpAHQAZQByAGEAYgBsAGUAKQAgAHsACgAgACAAIAAgAHkAaQBlAGwAZAAgAHYAIAArACAAbgA7AAoAIAAgAH0ACgB9AAoACgBmAHUAbgBjAHQAaQBvAG4AKgAgAHAAbAB1AHMAVABoAHIAZQBlAEUAdgBlAHIAeQB0AGgAaQBuAGcAQQBuAGQAVABoAGUAbgBQAGwAdQBzAFQAdwBvAEUAdgBlAHIAeQB0AGgAaQBuAGcAKAAKACAAIABpAHQAZQByAGEAYgBsAGUAOgAgAEEAcwB5AG4AYwBJAHQAZQByAGEAYgBsAGUAPABuAHUAbQBiAGUAcgA%2BACwACgApACAAewAKACAAIAB5AGkAZQBsAGQAKgAgAHAAbAB1AHMAKABpAHQAZQByAGEAYgBsAGUALAAgADMAKQA7AAoAIAAgAHkAaQBlAGwAZAAqACAAcABsAHUAcwAoAGkAdABlAHIAYQBiAGwAZQAsACAAMgApADsACgB9AAoA
EDIT: the code above is a bit silly because the second
plus(…)call doesn't do anything — the iterator is already consumed. See below for an example that can't be trivially rewritten.Biome errors and tells me that the
asynckeyword is unnecessary:However, removing the
asyncwould cause the code to break, because we are yielding to anasynciterable.Expected result
No error.
I'm not sure exactly what the best course of action here is. The simplest would be to count
yield*similar to anawaitcall in anasyncfunction — that's probably what I would do to eliminate false positives. Butyield* …can also be used to yield to sync generators (even from insideasyncfunctions), so this would allow false negatives.1However, the code is concise and idiomatic for combinators of iterables. It doesn't feel right to rewrite it or to add a permanent comment for Biome to ignore it.
Code of Conduct
Footnotes
Conceptually, using
yield*exclusively on known-sync generators in anasyncfunction feels similar toawaiting a non-thenable, but TypeScript tends to warn in that case. To report proper diagnostics, Biome would have to know the types of all the iterables thatawait*is used on. ↩