Copying an invitation link from the workspace Invitations tab yields a URL that cannot be opened. The recipient of an invitation therefore has no working way in.
Repro
- Multi-org runtime, zh console, sign up and create a workspace (owner).
- Users → Invite user → invite
lisi@acme-test.com as member.
- Workspace switcher → Manage members → Invitations tab → click Copy invitation link.
- Paste the clipboard content.
Actual
http://localhost:8080./accept-invitation/bgn1XAfRuCQUS1l9NBqOMGgJDUYm5l56
Two defects in one string:
- trailing-dot host —
localhost:8080. (the port is followed by .);
- the console mount is missing — the console is served under
/_console/, and GET /accept-invitation/<id> (dot removed) is answered by the server with {"error":"Not found"}.
The only URL that renders the accept page is http://localhost:8080/_console/accept-invitation/<id> — verified working, the page loads and the invitation can be accepted.
Expected
The copied link is the one the recipient can open: <origin><console mount>accept-invitation/<id>.
Cause
buildAcceptUrl rebuilds the URL from import.meta.env.BASE_URL, which is '.' in a portable (base: './') build:
// packages/app-shell/src/console/organizations/manage/InvitationsPage.tsx:32
function buildAcceptUrl(invitationId: string): string {
const base = (import.meta as any).env?.BASE_URL ?? '/';
const normalized = base.endsWith('/') ? base : `${base}/`;
return `${window.location.origin}${normalized}accept-invitation/${invitationId}`;
}
Duplicated verbatim in packages/app-shell/src/console/organizations/manage/InviteMemberDialog.tsx:39 (the "share link" view of the invite dialog), so the freshly-created-invitation link is broken the same way.
This is the exact failure mode resolveHomeUrl.ts was written to retire — its header documents it:
${origin}${import.meta.env.BASE_URL}home broke portable builds (base: './'), producing https://host./home — trailing-dot host.
Suggested fix
Drop both local buildAcceptUrl copies and call the existing mount-aware helper:
import { resolveConsoleUrl } from '../resolveHomeUrl';
const url = resolveConsoleUrl(`accept-invitation/${invitationId}`);
resolveConsoleUrl resolves against <base href> (the deployment mount), which is what both WorkspaceSwitcher and OrganizationsPage already use for full-page navigations. A regression test asserting the copied URL contains no :<port>. and starts with the console mount would pin it.
Environment
Local dev server http://localhost:8080, multi-org enabled, zh locale, observed 2026-08-12. The server was started by the maintainer and its exact commit is not verified; the source quoted above is the current objectui main checkout.
Copying an invitation link from the workspace Invitations tab yields a URL that cannot be opened. The recipient of an invitation therefore has no working way in.
Repro
lisi@acme-test.comasmember.Actual
Two defects in one string:
localhost:8080.(the port is followed by.);/_console/, andGET /accept-invitation/<id>(dot removed) is answered by the server with{"error":"Not found"}.The only URL that renders the accept page is
http://localhost:8080/_console/accept-invitation/<id>— verified working, the page loads and the invitation can be accepted.Expected
The copied link is the one the recipient can open:
<origin><console mount>accept-invitation/<id>.Cause
buildAcceptUrlrebuilds the URL fromimport.meta.env.BASE_URL, which is'.'in a portable (base: './') build:Duplicated verbatim in
packages/app-shell/src/console/organizations/manage/InviteMemberDialog.tsx:39(the "share link" view of the invite dialog), so the freshly-created-invitation link is broken the same way.This is the exact failure mode
resolveHomeUrl.tswas written to retire — its header documents it:Suggested fix
Drop both local
buildAcceptUrlcopies and call the existing mount-aware helper:resolveConsoleUrlresolves against<base href>(the deployment mount), which is what bothWorkspaceSwitcherandOrganizationsPagealready use for full-page navigations. A regression test asserting the copied URL contains no:<port>.and starts with the console mount would pin it.Environment
Local dev server
http://localhost:8080, multi-org enabled, zh locale, observed 2026-08-12. The server was started by the maintainer and its exact commit is not verified; the source quoted above is the currentobjectuimain checkout.