Moved from objectstack-ai/objectstack#8090 at triage (file-at-destination: the fix is entirely in this repo). Filed 2026-08-12 by @baozhoutao from a multi-org console walkthrough, original grading priority:p1. Batch siblings: objectstack-ai/objectstack#8091 #8092 #8093 #8094 (see that thread).
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/ (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: <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:32functionbuildAcceptUrl(invitationId: string): string{constbase=(import.meta asany).env?.BASE_URL??'/';constnormalized=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';consturl=resolveConsoleUrl(`accept-invitation/${invitationId}`);resolveConsoleUrl resolves against 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 :. 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 objectui main checkout at filing time.
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/(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:
<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 the deployment mount, which is what bothWorkspaceSwitcherandOrganizationsPagealready use for full-page navigations. A regression test asserting the copied URL contains no:.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 theobjectuimain checkout at filing time.