Repository navigation
fix(mcp): let ChatGPT save to the default space when the account has no spaces - #1889
Conversation
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ble active space Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | 9a96d2c | Commit Preview URL Branch Preview URL |
Nov 11 2026, 06:31 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-mcp | 9a96d2c | Nov 11 2026, 06:31 AM |
| textContent( | ||
| await deps | ||
| .getSession() | ||
| .then(emptySpacesMessage, () => "No spaces found."), |
There was a problem hiding this comment.
A failed session lookup is swallowed, so an operator cannot tell an auth outage from an empty account.
| .then(emptySpacesMessage, () => "No spaces found."), | |
| .then(emptySpacesMessage, (error) => { | |
| console.error("list_spaces session lookup failed:", error) | |
| return "No spaces found." | |
| }), |
|
Note This change is unlikely to harm production. I checked supermemory-mcp in production: 26k–47k requests/hour over 72h, 0 invocation errors, p99 CPU flat at 71 ms. The runtime diff adds optional view fields and a widget-side create-space picker only. No server-side space check, binding, or env value changes. Also considered · 4 refuted
Analysed against 1 Cloudflare Worker and 1 repository
Polylane analysed Previous verdicts (5)
|
Callers who can write new tags get console's type-to-create in the space picker and a first-space prompt when they have no spaces, instead of the sm_project_default fallback. Read-only, scoped and restricted callers keep their granted spaces only. Direct add_memory still falls back to the default. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…e spaces Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…paces Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ing spaces Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
| await deps | ||
| .getSession() | ||
| .then(emptySpacesMessage, () => "No spaces found."), | ||
| ), |
There was a problem hiding this comment.
Records the failed session read, so a backend failure is no longer indistinguishable from a genuine empty space list.
| await deps | |
| .getSession() | |
| .then(emptySpacesMessage, () => "No spaces found."), | |
| ), | |
| await deps.getSession().then(emptySpacesMessage, (error) => { | |
| console.error("list_spaces session lookup failed:", error) | |
| return "No spaces found." | |
| }), |
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
| await deps | ||
| .getSession() | ||
| .then(emptySpacesMessage, () => "No spaces found."), |
There was a problem hiding this comment.
The rejection handler hides why the empty-spaces message fell back, so an operator cannot count or diagnose failed session lookups.
| await deps | |
| .getSession() | |
| .then(emptySpacesMessage, () => "No spaces found."), | |
| await deps | |
| .getSession() | |
| .then(emptySpacesMessage, (error) => { | |
| console.warn( | |
| "No spaces found: session lookup failed for the empty-spaces message.", | |
| error instanceof Error ? error.message : String(error), | |
| ) | |
| return "No spaces found." | |
| }), |
Problem
ChatGPT users with Read and write access and zero spaces could not save: the Add Memory and Upload widgets had no space to offer, so Save stayed disabled (support ticket T-2159). Instead of silently falling back to
sm_project_default, the widgets now offer console's "Search or create tags…" combobox, so the user can type a name and create the space in place.flowchart LR S[guided-save / upload-file] --> G{canCreateNamespace?<br/>not read-only, not scoped,<br/>not restricted} G -- yes --> P[Search or create tags combobox<br/>0 spaces: empty, Save disabled until a tag is created<br/>has spaces: list + Create <tag>] G -- no --> L[Granted spaces only<br/>or blocked reason] P --> W[save-memory / upload with new tag<br/>space created on first write] A[add_memory from chat, 0 spaces] --> D[sm_project_default fallback, unchanged]Changes
canCreateNamespacemirrors the API write guard: a new tag is writable only without a read-only grant, a scoped-key tag list, or a restricted-member allowlist.spaceWriteTargetsfeeds both widget tools: creators get their spaces plus the active one, but with no spaces at all they get an empty list (no default fallback, no stale active space) andcanCreateNamespace: true; everyone else keeps the granted list, active space included, andwriteBlockedReason.SpaceField(shared by Save and Upload): one "Search or create tags…" combobox for zero and existing spaces. With zero spaces nothing is preselected, Save/Upload stays disabled and the hint reads "Type a name to create your first space". A "Saved as " hint appears only when sanitizing changed the typed name (e.g. "Reading list" →Reading_list).SpaceSelectgainsonCreate: "Search or create tags…" placeholder, "Create " row, Enter to create, hidden when the tag already exists (case-insensitive).sanitizeNamespace/isValidNamespacecopy console-v2'ssanitizeContainerTag/isValidContainerTag, so the widget saves the same key the console would.add_memory,list_spacesandselect-spacekeep thesm_project_defaultfallback and copy from the earlier commits.Verification
Local mono API (wrangler + Postgres) with this worker at c7eb3ee on
wrangler dev. The harness makes the widget's own calls:guided-save/upload-filefor the payload, the widget'ssanitizeNamespaceand create-row rule for the typed name, thensave-memoryorprepare-file-uploadplus a multipart POST. Syntheticsm_keys only; no staging or production data.writableNamespaces: [], nothing preselected, "+ Create Reading_list", "Saved as Reading_list"Reading_list;list_spacesand the nextguided-savelist itRecipesMeeting_noteswork)canCreateNamespace: false, no create row (Save and Upload)Recipessave and upload refused: "Access restricted to work"canCreateNamespace: false, no create row (Save and Upload)Recipessave and upload refused: "Access restricted to notes, team"add_memoryfrom chat, 0 spacessm_project_defaultfallback (server unchanged since 8734c7e run)tsc(server + widget),biome checkandvitest run srcpass.LOCAL SYNTHETIC: widget studio preview taken at c7eb3ee, rendering the real Save/Upload components with mock data. Still matches 9a96d2c, which only deletes a test file.