Skip to content

fix(core): honor runtime output dir for auto memory - #4715

Merged
tanzhenxin merged 2 commits into
QwenLM:mainfrom
he-yufeng:fix/memory-runtime-output-dir
Jun 8, 2026
Merged

fix(core): honor runtime output dir for auto memory#4715
tanzhenxin merged 2 commits into
QwenLM:mainfrom
he-yufeng:fix/memory-runtime-output-dir

Conversation

@he-yufeng

Copy link
Copy Markdown
Contributor

Summary

Verified

  • npm run test --workspace=packages/core -- src/memory/store.test.ts
  • npm run typecheck --workspace=packages/core
  • npx eslint packages/core/src/memory/paths.ts packages/core/src/memory/store.test.ts
  • git diff --check

return process.env['QWEN_CODE_MEMORY_BASE_DIR'];
}
return Storage.getGlobalQwenDir();
return Storage.getRuntimeBaseDir();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Critical] _autoMemoryRootCache cross-session contamination in daemon modepaths.ts:99

_autoMemoryRootCache is keyed only by projectRoot, but the cached value depends on getMemoryBaseDir()Storage.getRuntimeBaseDir(), which varies per AsyncLocalStorage context (set by runWithRuntimeBaseDir per session in daemon mode). clearAutoMemoryRootCache() is never called in production code.

In daemon mode, when two concurrent sessions have different runtimeOutputDir for the same project root, the first session to call getAutoMemoryRoot() caches its resolved path. The second session silently reads/writes memory in the wrong directory. This also affects isAutoMemPath permission checks in write/edit/read tools.

const _autoMemoryRootCache = new Map<string, string>();

export function getAutoMemoryRoot(projectRoot: string): string {
  const cacheKey = `${getMemoryBaseDir()}\0${projectRoot}`;
  const cached = _autoMemoryRootCache.get(cacheKey);
  if (cached !== undefined) return cached;

[Suggestion] QWEN_CODE_MEMORY_BASE_DIR doesn't resolve pathspaths.ts:89

Returns the raw env var string without path.resolve(). Compare with Storage.getRuntimeBaseDir() which resolves paths via resolvePath(). A tilde-prefixed value (~/my-memory) would be used literally.

    return path.resolve(process.env['QWEN_CODE_MEMORY_BASE_DIR']);

[Suggestion] Test coverage gapsstore.test.ts

  1. No test verifies that QWEN_RUNTIME_DIR env var (highest-priority path inside getRuntimeBaseDir()) drives memory paths correctly through getAutoMemoryRoot.
  2. No test checks what happens when runtimeBaseDir changes between two getAutoMemoryRoot calls without clearing the cache — the exact production scenario behind the Critical cache bug above.

— qwen3.7-max via Qwen Code /review

return process.env['QWEN_CODE_MEMORY_BASE_DIR'];
}
return Storage.getGlobalQwenDir();
return Storage.getRuntimeBaseDir();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Critical] Changing from getGlobalQwenDir() to getRuntimeBaseDir() silently relocates auto-memory from ~/.qwen/projects/... to <runtimeOutputDir>/projects/.... There is no migration logic, no symlink, and no fallback read from the old path. Users who have advanced.runtimeOutputDir set in settings.json will experience unexplained loss of all accumulated auto-memory (user preferences, project knowledge, feedback).

Suggested fix: Add a one-time migration — when the new path doesn't exist but the old getGlobalQwenDir()-based path does, either copy/symlink the old tree or fall back to reading from the old path with a deprecation log.

— qwen3.7-max via Qwen Code /review

@tanzhenxin tanzhenxin added the type/bug Something isn't working as expected label Jun 3, 2026
@he-yufeng

Copy link
Copy Markdown
Contributor Author

Pushed 389a389 for the review feedback.

Changes:

  • keyed the auto-memory root cache by the runtime-specific memory base dir plus project root, so daemon sessions with different runtime output dirs no longer reuse each other's managed memory root;
  • resolved QWEN_CODE_MEMORY_BASE_DIR before using it, matching the absolute-path behavior expected by the other runtime path settings;
  • added regression coverage for QWEN_RUNTIME_DIR priority, runtime-context cache separation without clearing the cache, and relative QWEN_CODE_MEMORY_BASE_DIR resolution.

Validation:

  • npm run test --workspace=@qwen-code/qwen-code-core -- src/memory/store.test.ts — 10 passed
  • npx eslint packages/core/src/memory/paths.ts packages/core/src/memory/store.test.ts
  • npm run typecheck --workspace=@qwen-code/qwen-code-core
  • npx prettier --check packages/core/src/memory/paths.ts packages/core/src/memory/store.test.ts
  • git diff --check

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found. LGTM! ✅ — qwen3.7-max via Qwen Code /review

@tanzhenxin tanzhenxin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Re-reviewed against the latest commit. The earlier concern — the auto-memory root cache being keyed only by project root, which could serve a stale root once the memory base became runtime-dependent — is resolved: the cache key now includes the runtime base dir (and the local-memory flag), with added test coverage for the multi-runtime case.

Remaining items are low-severity and fine as follow-ups: a release-notes line for users who already set a runtime dir (their existing ~/.qwen memory tree becomes orphaned, not lost), and a docs refresh for the now-relative memory path.

Verdict

APPROVE — correct, runtime-consistent fix for the split-root bug; the one substantive concern from the prior pass is fixed with tests, and only doc/migration polish remains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/bug Something isn't working as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto memory storage doesn't respect runtimeOutputDir configuration

3 participants