biomejs/biome · error
{owner} must return Promise
Error message
{owner} must return Promise What it means
The construct signature (or a validated member's) return type must be a direct reference to `Promise`, not another type. This bail fires in `validate_promise_reference` when the return type node is not a TsReferenceType at all — e.g. a union, an intersection, a literal, or a mapped type. The owner name is interpolated into the message so the offending declaration is identifiable.
Source
Thrown at xtask/codegen/src/generate_global_types/lower.rs:1124
bail!("Promise constructor executor must not be generic");
}
let executor_return_type = regular_return_type(executor.return_type()?, "Promise constructor")?;
if !matches!(executor_return_type, AnyTsType::TsVoidType(_)) {
bail!("Promise constructor executor must return void");
}
let return_type = member
.type_annotation()
.context("Promise constructor is missing a return type")?
.ty()
.context("Promise constructor has a malformed return type")?;
validate_promise_reference(&return_type, "Promise constructor")
}
/// Requires `Promise<...>` without constraining the declaration's projected type argument.
fn validate_promise_reference(type_node: &AnyTsType, owner: &str) -> Result<()> {
let AnyTsType::TsReferenceType(reference) = type_node else {
bail!("{owner} must return Promise");
};
let name = reference
.name()
.with_context(|| format!("{owner} has a missing return type name"))?;
let biome_js_syntax::AnyTsName::JsReferenceIdentifier(identifier) = name else {
bail!("{owner} must return Promise");
};
if identifier.value_token()?.token_text_trimmed().text() != "Promise" {
bail!("{owner} must return Promise");
}
let type_arguments = reference
.type_arguments()
.with_context(|| format!("{owner} must return Promise with one type argument"))?;
let mut arguments = type_arguments.ts_type_argument_list().into_iter();
let Some(argument) = arguments.next() else {
bail!("{owner} must return Promise with one type argument");
};
argument.with_context(|| format!("{owner} has a malformed Promise type argument"))?;View on GitHub (pinned to 3835945f06)
Solutions
- Change the return type to a plain `Promise<T>` reference
- Remove unions/intersections/modifiers around the return type
- If a wrapper type is needed, validate it separately instead of routing it through validate_promise_reference
Example fix
// before new <T>(executor: ...): Promise<T> | PromiseLike<T>; // after new <T>(executor: ...): Promise<T>;
Defensive patterns
Strategy: validation
Validate before calling
// Return type must be a plain reference, not a union/intersection/literal
let ret = "Promise<T>";
assert!(!ret.contains('|') && !ret.contains('&'), "return type must be a bare Promise reference"); Prevention
- Keep validated return types as bare `Promise<...>` references
- Model nullable/alternative returns elsewhere, not in codegen-validated declarations
- Check which validator a declaration routes through before changing its shape
When it happens
Trigger: Running global-types codegen when a validated declaration's return type is `PromiseLike<T> | Promise<T>`, `readonly Promise<T>`, `T`, or any non-reference type node instead of a plain `Promise<...>` reference.
Common situations: Editing the bundled global declarations and changing a return type to a union or alias; a parser change producing a different AnyTsType variant for what looks like a reference.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- declare var Promise is missing a type annotation
- Promise global must include declare var Promise
- Promise constructor must have one required executor paramete
- Promise constructor executor must be a function type
- Promise constructor executor must not be generic
AI-assisted analysis of biomejs/biome@3835945f06 (2026-09-13).
Data as JSON: /api/errors/d3fb62e321da1d5d.
Report an issue: GitHub.