Azure / Azure/azure-rest-api-specs
[BUG] TypeSpec Validation: StaleApiVersionPin fails with "emitter-not-found: @azure-tools/typespec-metadata" after the September 2026 TypeSpec upgrade (#46261)
- Dominant language
- TypeSpec
- Stars
- 3.1k
- Forks
- 5.9k
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 424
Description
### API Spec link
https://github.com/Azure/azure-rest-api-specs/blob/main/specification/azureresiliencemanagement/resource-manager/Microsoft.AzureResilienceManagement/AzureResilienceManagement/main.tsp
### API Spec version
2026-09-30-preview
### Describe the bug
The required `TypeSpec Validation` check fails for **any PR that adds exactly one new API version**, because the `StaleApiVersionPin` rule depends on an emitter that is no longer installed.
**Root cause:** commit `b2454e9bc937281e76f1fd246d2389e647c31315` ("Upgrade TypeSpec packages to September 2026 releases", #46261, merged 2026-09-10T19:05:31Z) removed the emitter from `package.json` instead of upgrading it:
```diff
- "@azure-tools/typespec-metadata": "0.3.0",
```
Every other dependency in that diff has a matching `+` line (`@typespec/compiler` 1.15.0 → 1.16.0, `@azure-tools/typespec-autorest` 0.71.0 → 0.72.0, `@typespec/versioning` 0.85.0 → 0.86.0, …). This is the only entry dropped with no replacement — hence `package.json` being `+17 −18`.
The emitter is still invoked. `.github/shared/src/typespec-metadata.js` runs:
```js
await execNpmExec([
"tsp", "compile", tspCompileTarget,
"--emit", "@azure-tools/typespec-metadata",
...
]);
```
and `eng/tools/typespec-validation/src/rules/stale-api-version-pin.ts` calls `generateTypeSpecMetadata(folder)` from `@azure-tools/specs-shared/typespec-metadata`. The package is declared in neither `package.json` nor `.github/shared/package.json`.
**Why it was likely dropped:** the latest published release is incompatible with the new toolchain.
```console
$ npm view @azure-tools/typespec-metadata@latest version peerDependencies
{
"version": "0.3.0",
"peerDependencies": {
"@azure-tools/typespec-azure-core": "^0.71.0",
"@azure-tools/typespec-client-generator-core": "^0.71.0",
"@typespec/compiler": "^1.15.0",
"@typespec/versioning": "^0.85.0"
}
}
```
The repo now ships compiler 1.16.0 and the Azure libraries at 0.72.0, so `0.3.0` no longer satisfies its peer ranges. Published versions are `0.1.0 … 0.3.0` plus prereleases `0.3.1-dev.0` / `0.3.1-dev.1` — there is **no stable 0.72/1.16-compatible release**. The automated bump appears to have removed the entry rather than holding the upgrade back. The package was maintained until then — see `961b0d9656d` (#45105).
**Note this is not fixable by simply restoring the line**, since no compatible version exists yet.
**Blast radius.** The same emitter is referenced by `eng/tools/release-plan/src/typespec-project.ts`, `eng/tools/spec-gen-sdk-runner/` (`commands.ts`, `emitter-check.ts`, `command-helpers.ts`, `azsdk-adapter.ts`), `eng/scripts/Create-APIView.ps1`, `.github/workflows/src/package-name-approval/detect-namespaces.js`, and the sibling rules `multiple-new-api-versions.ts` / `sdk-api-version.ts`.
**Suggested fix**
1. Publish a `@azure-tools/typespec-metadata` release compatible with `@typespec/compiler` ^1.16.0 and the 0.72.0 Azure libraries, then restore it to `package.json`; **or**
2. Make `StaleApiVersionPin` and the other consumers degrade gracefully — skip with a warning when the emitter cannot be resolved, rather than failing a required check; **or**
3. Temporarily revert the `@typespec/*` portion of #46261 until a compatible emitter release exists.
Option 2 seems worth doing regardless, so that a missing optional emitter cannot block every new-api-version PR in the repo.
### Expected behavior
`TypeSpec Validation` should pass for a PR that adds a single new API version and whose TypeSpec compiles cleanly with no generated-output drift.
`StaleApiVersionPin` should either evaluate SDK emitter pins successfully, or — if its optional metadata emitter cannot be resolved — skip with a warning rather than fail a required, merge-blocking check.
### Actual behavior
The rule aborts and fails the check. All other rules pass in the same run: `Compilation completed successfully`, no generated-output diff, `Format` ✓, `SdkTspConfigValidation` ✓, `MultipleNewApiVersions` skipped. `StaleApiVersionPin` is the sole failure.
```
Executing rule: StaleApiVersionPin
Rule StaleApiVersionPin failed
Error: Failed to generate TypeSpec metadata: TypeSpec compiler v1.16.0
Diagnostics were reported during compilation:
error emitter-not-found: Emitter "@azure-tools/typespec-metadata" not found. Make sure to install it with `npm install @azure-tools/typespec-metadata`.
Found 1 error.
No emitter was configured, no output was generated. Use `--emit ` to pick emitter or specify it in the TypeSpec config.
##[error]TypeSpec Validation failed for project specification/azureresiliencemanagement/resource-manager/Microsoft.AzureResilienceManagement/AzureResilienceManagement
```
Failing run: https://github.com/Azure/azure-rest-api-specs/actions/runs/34567887662/job/103163633430 (PR #45819)
### Reproduction Steps
```bash
npm ci
npx tsv specification/
```
Or open/update any PR that adds exactly one new API version and observe `TypeSpec Validation`.
`StaleApiVersionPin` only runs when a PR adds exactly one new API version, which is why the breakage is not universal. Open `new-api-version` PRs that currently show green all last ran **before** the upgrade landed at 19:05 UTC, and will fail on their next run:
| PR | `TypeSpec Validation` last run | Result |
|---|---|---|
| #46264 | 2026-09-10 18:21 | ✅ |
| #46210 | 2026-09-10 16:30 | ✅ |
| #46262 | 2026-09-10 16:28 | ✅ |
| #46250 | 2026-09-10 09:44 | ✅ |
| #45819 | 2026-09-11 05:57 | ❌ |
### Environment
- **CI:** GitHub Actions, `ubuntu-24.04` (`TypeSpec Validation - Analyze Code` workflow)
- **Node:** `>=24.14.1` (per root `package.json` `engines`)
- **TypeSpec compiler:** 1.16.0 (was 1.15.0 before #46261)
- **Azure TypeSpec libraries:** 0.72.0 (were 0.71.0)
- **Repo state:** `main` at or after `b2454e9bc937281e76f1fd246d2389e647c31315`
- Reproduces locally with `npm ci && npx tsv `; not environment-specific — the dependency is absent from the committed manifests.
Contributor guide
Research direction
Start with npm ci && npx tsv on a folder adding exactly one API version, then read package.json, .github/shared/src/typespec-metadata.js, and eng/tools/typespec-validation/src/rules/stale-api-version-pin.ts. Trace the other listed metadata consumers and determine how the missing emitter should be handled. Done means TypeSpec Validation passes without failing on emitter-not-found, while clean TypeSpec output remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, nodejs, typescript
- Domain
- ci-cd, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100