Chapter 27. 2026-07-17: The Origin That Was Never Allowlisted
WalletConnect returns an
Origin ... not found on Allowlist error when the domain
serving your app is missing from the Reown Cloud project’s
allowed-origins list, config that lives in a vendor dashboard and not in
your repository. On 2026-07-17 an agent session ran a live Lighthouse
pass against https://social.suedeai.ai/ to verify PR #658, a hydration
fix. The PR checked out. The console did not:
Origin https://social.suedeai.ai not found on Allowlist - update configuration on cloud.reown.com
Next to the error sat two network 403s from the WalletConnect relay, same root cause. The relay was refusing the social surface’s origin in production. No one had to click a wallet button to trigger it; the refusal appeared on a page load, during a performance check aimed at something else.
The session was not hunting wallet bugs. It found one because verification on this estate runs against production with the console visible, and a visible console reports what is there, not what you came for.
The half of the config that lives in Reown’s database
Reown, the company operating WalletConnect Cloud, gates its relay per origin. You register the domains your app serves in the project dashboard at cloud.reown.com, and a request from an unregistered origin gets a 403. That is a defensible design for a relay operator. For an operator on my side of it, it means part of the integration’s production config lives in a place no repository represents.
Everything checkable in code checked out. The project ID was
identical in frontend/.env.local and in the pulled Vercel
production env, under both names the code reads:
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID and
WALLETCONNECT_PROJECT_ID. The wiring sat where it should:
wagmi’s walletConnect connector in
frontend/src/components/EvmProvider.tsx, mounted through
frontend/src/components/WalletProviders.tsx in two places,
src/app/(app-host)/layout.tsx and
src/app/social/layout.tsx. Build green, types green, env
verified against the deployed values rather than local copies.
An integration like this carries its config in two halves. One half lives in my repo: the project ID, the connector wiring, the env vars. The other half lives in Reown’s database: the list of origins allowed to speak to the relay. The two halves get checked against each other in one place, at runtime, in a visitor’s browser, by the relay itself. No stage of my pipeline compares them.
None of it mattered. The dashboard had never heard of social.suedeai.ai.
Why social.suedeai.ai was never registered
The diagnosis note states the root cause without decoration: nobody had checked whether social.suedeai.ai, unlike studio, was ever registered in Reown’s allowed-origins list before PR #655 scoped the wallet stack down to app-host plus social. It was broken in production with no signal. How long it had been broken, the record cannot say; “ever registered” is the operative phrase.
The pairing carries an irony. Studio, the surface being cut away from the wallet stack in PR #655, was on the allowlist. Social, the surface keeping the stack, never was. Registration had followed the history of who integrated first, not the map of who needed the capability.
And social does need it. SignInButton mounts
SignInModal on demand, and the modal calls wallet hooks for
signed-out visitors across feed, forum, notifications, and settings. A
guitarist who has never held a wallet still walks that code path by
opening the sign-in modal. Cutting the stack from social was not an
option, because the sign-in surface depends on it.
Allowlist the origin, or remove the wallet stack
Studio and social presented the same class of brokenness on the same day and received opposite treatments.
| Surface | Needs wallet hooks | Fix |
|---|---|---|
| studio.suedeai.ai | No | PR #655, merged 2026-07-17: wallet stack removed from the surface |
| social.suedeai.ai | Yes, via SignInModal for signed-out visitors |
Origin added to the Reown project allowlist |
| suede.social | Same app tree, same social surface | Origin added in the same change |
The deciding question was not which fix makes the error disappear; both do. The question was whether the surface has a live reason to carry the capability. Studio has no wallet interaction anywhere in its product, so PR #655 deleted the stack from it rather than teach a dashboard to tolerate it. Social’s sign-in flow exercises the hooks, so social got registered. Matching the fix to the symptom would have allowlisted both, and studio would still be hauling a wallet stack it never uses.
The fix: two origins added to the Reown allowlist
The fix was two entries typed into a settings page: add
https://social.suedeai.ai and
https://suede.social to the allowed origins of Reown
project [REDACTED-PROJECT-ID]. It touched no file in the
repo, so it produced no PR number, no commit hash, and no CI run, the
artifacts a normal fix leaves behind. The change history for this
incident lives in a third party’s dashboard and in my notes, nowhere
else.
The session that diagnosed the problem did not apply the fix. The agent had no Reown Cloud credentials, and my standing rules keep agents out of credentialed third-party dashboards: the job is to surface the exact change and wait for my sign-off. That boundary held. The incident writeup ends with the change spelled out, the project ID named, and the work parked pending authorization. I signed off, both origins went in on 2026-07-17, and rerunning the check that had found the failure came back clean: zero console errors from the social origin.
The second origin is the part the error message never showed.
suede.social had thrown no error in front of anyone; the diagnosis note
marks it as “almost certainly has the identical 403.” It went onto the
allowlist because of an enumeration, not a symptom.
next.config.ts confirms the same app tree also serves
suede.social and play.suedeai.ai, so when a per-origin config comes up,
the move is to read the domain list out of that file and register the
relevant domains together. Fixing only the domain named in the console
schedules the identical incident for the next domain a member happens to
use.
The estate’s shape raises the stakes on that rule. The Suede-AI-App frontend serves 8 hosts from one root layout: app, social, studio, play, agents, ip, fretpulse, distro. One codebase, one integration, one project ID, many origins. A per-origin allowlist meets that topology as a set of independent failure points, one per domain, each invisible until someone loads the page from it.
Shipped means the dashboard lists every origin
A third-party allowlist is production configuration with no code
representation. It offers no file to grep, no type to check, no test to
fail, and npm run build cannot see cloud.reown.com. Each
artifact my tooling inspects can be correct while the feature is down on
a domain the dashboard has not met. The failure mode is invisible from
inside the repo by construction.
the definition of shipped tightens for integrations like this one. A per-origin integration is shipped when the provider’s dashboard lists the domains the app tree serves and the feature has been watched working from each of them. Before that, what you have is code that compiles and a demo that works on whichever origin happened to get registered first.
2026-07-17 pressed the point twice on the same wallet stack. PR #660, a wallet-connect lazy-load refactor, passed build, tsc, and lint, merged and deployed under standing autonomy, and broke the live Connect Wallet button on 6 marketing pages with a client-side exception on click. A manual click on an isolated browser tab caught it in about 10 minutes, and PR #661 reverted it. Two dead wallet features in one day, both behind green automated checks. One failure lived in a runtime path no build inspects; the other lived in a dashboard no repo contains.
Build, tsc, and lint inspect the repository. A member’s browser runs the product against the relay, the dashboard, and the deployed env all at once, and it reports the difference. Both of the day’s finds came from the same act: loading the live site with the console open and reading what it said. The Lighthouse pass that surfaced the Reown error was aimed at a hydration fix and earned its keep on a bug three layers from its target. Verification stays pointed at production on this estate because production is the one place where the repo, the deployed env, and the third party’s dashboard have to agree at once.