biomejs/biome · error

PromiseConstructor must have a type-side declaration

Error message

PromiseConstructor must have a type-side declaration

What it means

The 'PromiseConstructor' group must contain a type-side declaration (the PromiseConstructor interface) because the Promise value references it as a type. If the group exists but carries no GlobalDeclarationRole::Type record, lowering cannot generate the constructor type and bails with this error.

Source

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

                    record.text_range
                )
            })?;
        validate_promise_interface(&declaration)?;
        validate_promise_methods(
            &declaration,
            PromiseMemberLocation::Instance,
            &mut saw_methods,
        )?;
    }
    if !saw_promise_interface {
        bail!("Promise global must include an interface declaration");
    }

    let Some(constructor_group) = manifest.global_group("PromiseConstructor") else {
        bail!("Promise global value side references missing PromiseConstructor group");
    };
    if !constructor_group.has_role(GlobalDeclarationRole::Type) {
        bail!("PromiseConstructor must have a type-side declaration");
    }

    let mut saw_constructor_interface = false;
    let mut saw_construct_signature = false;
    for record in constructor_group.declarations() {
        match &record.kind {
            DeclarationKind::Interface => saw_constructor_interface = true,
            DeclarationKind::TypeAlias => {
                bail!("type aliases are not supported in PromiseConstructor")
            }
            DeclarationKind::DeclareFunction
            | DeclarationKind::VariableDeclarator { .. }
            | DeclarationKind::ImportEquals => {
                bail!("value-side PromiseConstructor declarations are not supported")
            }
        }

        let declaration = source_cache

View on GitHub (pinned to 3835945f06)

Solutions

  1. Restore `interface PromiseConstructor` (including its `new (...): Promise<any>` construct signature) in the PromiseConstructor global group.
  2. Verify role extraction tags that interface as GlobalDeclarationRole::Type within the group.
  3. Regenerate and re-run `cargo xtask codegen`.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the PromiseConstructor group has a type-side record
fn has_type_role(group: &GlobalGroup) -> bool {
  group.has_role(GlobalDeclarationRole::Type)
}
if !has_type_role(constructor_group) { bail!("PromiseConstructor lacks interface (Type role)"); }

Try / catch

if let Err(e) = lower_promise_globals(&manifest, &mut globals, &source_cache) {
  if e.to_string().contains("PromiseConstructor must have a type-side declaration") {
    eprintln!("Restore `interface PromiseConstructor` and rerun `cargo xtask codegen`");
    std::process::exit(1);
  }
  return Err(e.into());
}

Prevention

When it happens

Trigger: Running `cargo xtask codegen` when the PromiseConstructor group's records include only value-side entries (or none classified as Type) — e.g. the `interface PromiseConstructor` was deleted or its type role was lost during role extraction.

Common situations: Editing PromiseConstructor declarations and dropping the interface; a role-classification regression marks all records as value-side; splitting the constructor into separate files so the type-side record is no longer grouped.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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