Skip to content

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

Open
he-yufeng wants to merge 1 commit into
QwenLM:mainfrom
he-yufeng:fix/memory-runtime-output-dir
Open

fix(core): honor runtime output dir for auto memory#4715
he-yufeng wants to merge 1 commit 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

Copy link
Copy Markdown
Collaborator

@wenshao wenshao left a comment

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

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto memory storage doesn't respect runtimeOutputDir configuration

2 participants