OpenZeppelin / OpenZeppelin/ui-builder

Staging exports pin adapters to a stale `rc` dist-tag → shipped adapter predates published features (breaks ENS)

Open
#407 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
48
Forks
23
Avg merge
3h 1m
Merged PRs (30d)
10

Description

Summary

Staging-mode exports pin every @openzeppelin/adapter-* to the npm rc dist-tag, but that tag is stale. It currently resolves to 2.0.0-rc.1 (published 2026-04-03), which predates features later shipped as stable releases — most visibly the ENS / name-resolution featureset (stable 2.1.02.3.0). Result: a staging export silently installs a pre-feature adapter and the feature appears broken at runtime, even though the export scaffolding is correct.

Symptom (observed)

A freshly exported app (built-in Ethereum Sepolia, address form), exported in staging mode, shows:

Name resolution is not supported on this network

…when an ENS name is entered — despite ENS being fully wired into the export template (#401) and the UI packages being ENS-capable.

Evidence

Exported package.json (staging signature — UI pkgs stable, adapter on rc):

"@openzeppelin/ui-components": "^3.8.1",   // stable, ENS-capable ✅
"@openzeppelin/ui-react": "^3.3.0",
"@openzeppelin/ui-renderer": "^3.4.0",
"@openzeppelin/adapter-evm": "rc"          // ← resolves to stale 2.0.0-rc.1 ❌

Installed adapter + registry state:

adapter rc tag → latest (stable)
adapter-evm 2.0.0-rc.1 (Apr 3) 2.3.0
adapter-solana / -stellar / -midnight 2.0.0-rc.1 2.2.0
  • adapter-evm@2.0.0-rc.1 dist contains zero matches for resolveName / ensUniversalResolver — the name-resolution capability simply does not exist in that build, so the runtime reports UNSUPPORTED_NETWORK.
  • The ENS feature landed in stable 2.1.02.3.0 (July 2026), all via push-to-main stable releases. The RC path (publish.yml workflow_dispatch) was never run for it, so the rc dist-tag never advanced past April.

Root cause

apps/builder/src/export/PackageManager.tsapplyVersioningStrategy, env === 'staging' branch:

// Staging: Use RC versions for testing latest features
if (managedVersion.includes('-rc')) {
  updatedDependencies[pkgName] = managedVersion;
} else {
  // Otherwise fall back to the 'rc' dist-tag ...
  updatedDependencies[pkgName] = 'rc';
}

When versions.ts holds a stable semver (e.g. 2.3.0), staging pins the dependency to the bare 'rc' dist-tag. That is only correct if the rc tag is ≥ latest stable. It isn't — and nothing guarantees it. Any feature merged to stable after the last RC publish is invisible to staging exports, with no error at export time (silent regression surface).

Note: production-mode exports are unaffected — they pin ^<managedVersion> from versions.ts (e.g. ^2.3.0), so they ship ENS correctly.

Proposed fixes (any subset)

  1. PackageManager (primary): in the staging branch, only use the rc dist-tag when it is actually newer than the managed stable; otherwise fall back to ^<managedVersion> (i.e. never ship an adapter older than the production pin). Guards against tag lag structurally.
  2. Release hygiene: advance the rc dist-tag whenever a stable adapter release goes out (or run the RC workflow_dispatch after stable), so rc never trails latest.
  3. Preflight guard: a CI/export check that fails or warns when any @openzeppelin/adapter-* rc tag is older than its latest, so this can't silently recur.

References

  • Export ENS wiring: #401 (merged)
  • ENS featureset completeness in exports: #406
  • apps/builder/src/export/PackageManager.ts (applyVersioningStrategy)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/builder/src/export/PackageManager.ts at applyVersioningStrategy and inspect the staging branch that assigns the rc dist-tag. Compare that behavior with the managed stable version in versions.ts and verify the export output for staging and production adapters. Done means staging exports no longer resolve an adapter older than the production pin, while valid newer RC versions remain usable.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
build-system, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.