biomejs/biome · error

{owner} must return Promise with one type argument

Error message

{owner} must return Promise with one type argument

What it means

The final Promise-reference check requires exactly one type argument. This bail fires in two cases: the argument list is empty (no first argument), or there is more than one argument (e.g. `Promise<T, U>`). Errors in the single argument itself are reported separately as 'malformed Promise type argument'.

Source

Thrown at xtask/codegen/src/generate_global_types/lower.rs:1140

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"))?;
    if arguments.next().is_some() {
        bail!("{owner} must return Promise with one type argument");
    }
    Ok(())
}

/// Preserves whether lookup reaches the helper through an instance or the constructor.
fn promise_member(specification: PromiseMethodSpecification) -> LoweredTypeMember {
    let kind = match specification.location {
        PromiseMemberLocation::Instance => LoweredMemberKind::Named { optional: false },
        PromiseMemberLocation::Static => LoweredMemberKind::NamedStatic,
    };
    LoweredTypeMember {
        name: Text::from(specification.source_name),
        kind,
        type_reference: LoweredTypeReference::Predefined(specification.member_type_id),

View on GitHub (pinned to 3835945f06)

Solutions

  1. Keep exactly one type argument: `Promise<T>`
  2. Remove any extra type arguments beyond the first
  3. Ensure the argument list is non-empty (never `Promise<>`)

Example fix

// before
new <T>(executor: ...): Promise<T, U>;
// after
new <T>(executor: ...): Promise<T>;
Defensive patterns

Strategy: validation

Validate before calling

// Exactly one type argument required
let args = count_type_args("Promise<T>");
assert_eq!(args, 1, "Promise must have exactly one type argument");

Prevention

When it happens

Trigger: Running global-types codegen when a validated declaration returns `Promise<>`, `Promise<T, U>`, or `Promise<T, PromiseError>` — i.e. zero or 2+ type arguments.

Common situations: Porting a Promise-like type from another language/library with two parameters; typos adding a stray second argument; an empty argument list left after deleting a parameter.

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


AI-assisted analysis of biomejs/biome@3835945f06 (2026-09-13). Data as JSON: /api/errors/fc056bf5c7216de7. Report an issue: GitHub.