Skip to content

share_cube_with_user passes swapped args to _validate_cube_access — fails for every well-formed call #1901

@egouilliard-leyton

Description

@egouilliard-leyton

Upstream issue draft — MemOS share_cube_with_user

Where to file: https://github.com/MemTensor/MemOS/issues/new
Target repo: MemTensor/MemOS
Status check (2026-06-08): confirmed at b60616d (HEAD of main, also v2.0.18-dev); same code in PyPI MemoryOS==2.0.17. No existing issue found via gh issue list -R MemTensor/MemOS --search "share_cube_with_user".


Title

share_cube_with_user passes swapped args to _validate_cube_access, so every call fails with ValueError("User '<cube_id>' does not exist")

Body

Summary

MOSCore.share_cube_with_user(cube_id, target_user_id) is unusable in b60616d (main, v2.0.18-dev) / MemoryOS==2.0.17 on PyPI. The first line of the body calls _validate_cube_access with the wrong positional args — the validator's signature is (self, user_id, cube_id) but the call sends (cube_id, target_user_id). The validator then tries to verify the cube_id as a user_id and raises ValueError: User '<cube_id>' does not exist or is inactive.

Reproduce

import os, shutil
os.environ.setdefault("MOS_TEXT_MEM_TYPE", "general_text")
assert os.environ.get("OPENAI_API_KEY"), "set OPENAI_API_KEY"

from memos.mem_os.main import MOS

mos = MOS()  # auto-config from env
OWNER, TARGET = "owner_demo", "target_demo"
mos.create_user(OWNER)
mos.create_user(TARGET)

cube_id = mos.create_cube_for_user(cube_name="demo_cube", owner_id=OWNER)
mos.register_mem_cube(mos._auto_registered_cube, mem_cube_id=cube_id, user_id=OWNER)
mos.add(
    messages=[{"role": "user", "content": "hello world"}],
    user_id=OWNER, mem_cube_id=cube_id,
)

# Boom: ValueError: User '<uuid>' does not exist or is inactive.
mos.share_cube_with_user(cube_id=cube_id, target_user_id=TARGET)

Expected

share_cube_with_user(cube_id, target_user_id) grants target_user_id access to cube_id, returning True. The validation should confirm the current (sharing) user has access to the cube — matching the in-code comment "Validate current user has access to this cube".

Actual

Traceback (most recent call last):
  File ".../memos/mem_os/core.py", line 1173, in share_cube_with_user
    self._validate_cube_access(cube_id, target_user_id)
  File ".../memos/mem_os/core.py", line 225, in _validate_cube_access
    self._validate_user_exists(user_id)
  File ".../memos/mem_os/core.py", line 210, in _validate_user_exists
    raise ValueError(
ValueError: User '<cube_id>' does not exist or is inactive. Please register the user first.

The cube_id (a UUID) is being passed where user_id is expected.

Root cause

src/memos/mem_os/core.py:

# line 214 — validator expects (user_id, cube_id)
def _validate_cube_access(self, user_id: str, cube_id: str) -> None:
    self._validate_user_exists(user_id)
    if not self.user_manager.validate_user_cube_access(user_id, cube_id):
        raise ValueError(...)

# line 1162 — caller passes (cube_id, target_user_id)
def share_cube_with_user(self, cube_id: str, target_user_id: str) -> bool:
    # Validate current user has access to this cube
    self._validate_cube_access(cube_id, target_user_id)   # <-- args swapped
    ...

Two problems compounded:

  1. Positional args are swapped — cube_id lands in the user_id slot.
  2. The intent (per the comment) is to validate the current user, not target_user_id. The target is then separately validated on the next line via validate_user. So even with args corrected to (target_user_id, cube_id), the semantics would still be wrong — the call should use self.user_id.

Proposed fix (1 line)

 def share_cube_with_user(self, cube_id: str, target_user_id: str) -> bool:
     ...
     # Validate current user has access to this cube
-    self._validate_cube_access(cube_id, target_user_id)
+    self._validate_cube_access(self.user_id, cube_id)

     # Validate target user exists
     if not self.user_manager.validate_user(target_user_id):
         raise ValueError(...)

     return self.user_manager.add_user_to_cube(target_user_id, cube_id)

This matches the validator's signature, the docstring intent, and the natural security model (you must have access to the cube you're sharing).

Workaround (until fixed)

Bypass share_cube_with_user and call the underlying user_manager directly:

mos.user_manager.add_user_to_cube(target_user_id, cube_id)

(That's the last line of share_cube_with_user anyway.)

Environment

  • MemoryOS==2.0.17 (PyPI) — affected
  • b60616d (HEAD of main, v2.0.18-dev) — affected
  • Python 3.12.3 on Linux
  • Config: default MOS() with MOS_TEXT_MEM_TYPE=general_text, local Qdrant
  • Reproducible deterministically — no race / timing involved.

Metadata

Metadata

Assignees

Labels

ai-pr-readyAutoDev tests passed and PR is ready for human review/merge.bugSomething isn't working | 功能异常good first issueGood for newcomers | 适合新手help wantedExtra attention is needed | 需要社区帮助memosCore MemOS logic (memory, MCP, scheduler, API, database) | 核心模块

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions