Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/core/src/utils/memoryDiscovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,29 @@ describe('memoryDiscovery', () => {
});
});

it('should skip GEMINI.md directories without warnings', async () => {
vi.stubEnv('NODE_ENV', 'production');
vi.stubEnv('VITEST', '');
const warnSpy = vi.spyOn(debugLogger, 'warn').mockImplementation(() => {});

await createEmptyDir(path.join(projectRoot, DEFAULT_CONTEXT_FILENAME));

const result = await loadServerHierarchicalMemory(
cwd,
[],
false,
new FileDiscoveryService(projectRoot),
new SimpleExtensionLoader([]),
DEFAULT_FOLDER_TRUST,
);

expect(result.memoryContent).toBe('');
Copy link
Contributor

Choose a reason for hiding this comment

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

high

To make this test more robust and ensure the fileCount is accurate, please also assert that result.fileCount is 0. This verifies that skipped directories are not counted as loaded files. This change is related to the suggested fix in memoryDiscovery.ts to calculate fileCount more accurately.

expect(result.memoryContent).toBe('');
expect(result.fileCount).toBe(0);

expect(result.filePaths).toContain(
path.join(projectRoot, DEFAULT_CONTEXT_FILENAME),
);
expect(warnSpy).not.toHaveBeenCalled();
});

it('should load only the global context file if present and others are not (default filename)', async () => {
const defaultContextFile = await createTestFile(
path.join(homedir, GEMINI_DIR, DEFAULT_CONTEXT_FILENAME),
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/utils/memoryDiscovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ async function readGeminiMdFiles(

return { filePath, content: processedResult.content };
} catch (error: unknown) {
const errorCode =
typeof error === 'object' && error !== null && 'code' in error
? (error as NodeJS.ErrnoException).code
: undefined;
if (errorCode === 'EISDIR') {
if (debugMode) {
logger.debug(`Skipping directory at ${filePath}`);
}
return { filePath, content: null };
Comment on lines +277 to +281
Copy link
Contributor

Choose a reason for hiding this comment

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

high

Returning null content here correctly handles the EISDIR error without warnings. However, this reveals an issue in loadServerHierarchicalMemory where fileCount becomes misleading. It's calculated from the total number of paths discovered, including directories that are skipped here. This means the UI might report '1 file loaded' when it was a directory and no content was actually loaded.

To ensure accuracy, fileCount should reflect the number of successfully read files. I recommend updating loadServerHierarchicalMemory to filter for non-null content before counting:

// In loadServerHierarchicalMemory...
const successfullyReadFiles = contentsWithPaths.filter(
  (item) => item.content !== null
);

return {
  memoryContent: combinedInstructions,
  fileCount: successfullyReadFiles.length, // This is more accurate
  filePaths,
};

Since this is outside the current diff, I'm noting it here for you to consider as part of a complete fix.

}
const isTestEnv =
process.env['NODE_ENV'] === 'test' || process.env['VITEST'];
if (!isTestEnv) {
Expand Down