{"record":{"id":"8921febb3c5155fa","repo":"biomejs/biome","slug":"generated-helper-has-unexpected-shape","errorCode":null,"errorMessage":"generated {} helper has unexpected shape","messagePattern":"generated (.+?) helper has unexpected shape","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/codegen/src/generate_global_types/compare.rs","lineNumber":325,"sourceCode":"        LoweredMemberKind::Named { optional: false }\n    };\n    if member.kind() != &expected_kind\n        || member.type_reference() != &LoweredTypeReference::Predefined(shape.member_type_id)\n    {\n        bail!(\n            \"generated Promise.{} member has unexpected shape\",\n            shape.member_name\n        );\n    }\n\n    let helper = generated_function(lowered, shape.helper_name, shape.helper_id_constant)?;\n    if helper.is_async()\n        || !helper.type_parameters().is_empty()\n        || helper.name() != Some(shape.helper_name)\n        || !helper.parameters().is_empty()\n        || helper.return_type() != &LoweredTypeReference::Predefined(\"GLOBAL_INSTANCEOF_PROMISE_ID\")\n    {\n        bail!(\n            \"generated {} helper has unexpected shape\",\n            shape.helper_name\n        );\n    }\n    Ok(())\n}\n\n/// Rejects output that differs from the predefined `Array` projection used by the resolver.\nfn assert_array_shape(lowered: &LoweredGlobalTypes) -> Result<()> {\n    let Some(array) = lowered.global(\"Array\") else {\n        bail!(\"generated globals are missing the Array global\");\n    };\n    if array.id_constant() != \"ARRAY_ID_GLOBAL_TYPE_ID\" {\n        bail!(\n            \"generated Array global targets {}, expected ARRAY_ID_GLOBAL_TYPE_ID\",\n            array.id_constant()\n        );\n    }","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/biomejs/biome/blob/3835945f0638c88162351318b7bc8b64c5f2fba7/xtask/codegen/src/generate_global_types/compare.rs#L307-L343","documentation":"Biome's xtask codegen validates each generated Promise helper function (the GLOBAL_INSTANCEOF_PROMISE helpers): the helper must be non-async, have no type parameters, bear the expected helper name, take no parameters, and return the predefined GLOBAL_INSTANCEOF_PROMISE_ID type. Any deviation means the generator emitted a helper that downstream type lowering cannot rely on, so the build bails.","triggerScenarios":"Running `cargo xtask codegen` when generated_function() produced a helper whose signature drifted from the expected shape in assert_promise_method — e.g. a template/codegen change makes the helper async, adds type parameters or parameters, renames it, or alters its return type.","commonSituations":"Editing the helper-generation template in generate_global_types; renaming the GLOBAL_INSTANCEOF_PROMISE predefined id; a refactor of generated_function changing emission order or signatures.","solutions":["Inspect the generated helper for shape.helper_name and restore the expected signature: non-async, no type parameters, no parameters, return type GLOBAL_INSTANCEOF_PROMISE_ID.","Update the expected shape constant (helper_name / helper_id_constant) if the helper intentionally changed, then regenerate.","Re-run `cargo xtask codegen` and review the regenerated global types diff."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate generated helper signature before comparing\nfn validate_helper(helper: &LoweredFunction, shape: &PromiseShape) -> Result<()> {\n  ensure!(!helper.is_async(), \"helper {} must not be async\", shape.helper_name);\n  ensure!(helper.type_parameters().is_empty(), \"helper {} must have no type parameters\", shape.helper_name);\n  ensure!(helper.parameters().is_empty(), \"helper {} must take no parameters\", shape.helper_name);\n  Ok(())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = assert_promise_shape(&lowered, &shape) {\n  if e.to_string().contains(\"unexpected shape\") {\n    bail!(\"helper template drifted; regenerate globals: {e}\");\n  }\n  return Err(e);\n}","preventionTips":["When editing the helper-emission template, re-run `cargo xtask codegen` immediately.","Keep the GLOBAL_INSTANCEOF_PROMISE predefined id stable; update expectations in the same commit when renaming.","Snapshot the generated helper signature so template changes are visible in review diffs.","Do not add parameters or generics to Promise helpers without updating assert_promise_method."],"tags":["codegen","rust","build","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"3835945f0638c88162351318b7bc8b64c5f2fba7","analyzedAt":"2026-09-13T15:11:16.919Z","contentChangedAt":"2026-09-13T15:11:16.919Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}