Repository navigation
C# files with CRLF line endings + XML doc comments (///) silently parse to zero Method/Class nodes (v0.9.0, Windows) #1081
Description
Bug: C# files with CRLF line endings + XML doc comments (///) silently parse to zero Method/Class nodes (v0.9.0)
Summary
On v0.9.0 (Windows amd64), a C# file with CRLF line endings that contains XML documentation comments (///) silently fails to extract any structural nodes (Method/Class/Field) — the file degrades to producing only a single Module node with 0 Method, 0 Class, 0 CALLS. The indexer reports skipped_count: 0 and status: indexed (no error, no warning), so the failure is completely silent.
Converting the exact same file to LF line endings makes extraction work perfectly (full Method/Class/CALLS graph). Chinese/non-ASCII content is not the cause — it works fine under LF.
Environment
- Version: codebase-memory-mcp
0.9.0(also reproduced on0.8.1) - Platform: Windows 10 x64 (10.0.18363)
- Binary variant:
codebase-memory-mcp-ui-windows-amd64.zip - Language: C# (tree-sitter-c-sharp)
Reproduction
The file
A real C# file from a .NET project (UTF-8 with BOM, CRLF line endings, Chinese XML doc comments). Call it LearnTypeModel.cs:
using System.Collections.Generic;
using CommunityToolkit.Mvvm.ComponentModel;
namespace FX_TestModule.Models
{
/// <summary>
/// 学习类型数据模型(金板建模勾选状态)。
/// <para>
/// 所有学习开关(器件类型开关 + 条件选项,如 ModelR/ModelRCover/ModelCCT…)统一存在
/// <see cref="LearnSwitches"/> 字典里,key=开关名(由仪器 DLL 自报),value=勾选状态。
/// </para>
/// <para>
/// 仪器 DLL 端用 GetTestParamsValue<Dictionary<string,bool>>("LearnSwitches") 读取。
/// </para>
/// </summary>
public partial class LearnTypeModel : ObservableObject
{
public Dictionary<string, bool> LearnSwitches { get; } = new();
public bool GetSwitch(string key, bool defaultValue = false)
=> LearnSwitches.TryGetValue(key, out var v) ? v : defaultValue;
public void SetSwitch(string key, bool value) => LearnSwitches[key] = value;
}
}Important: the file must be saved with CRLF (
\r\n) line endings — this is the VS / Windows default. UTF-8 BOM presence is irrelevant (tested both).
Steps
# 1. Index as-is (CRLF) — BUG: only file-tree nodes
codebase-memory-mcp cli index_repository --repo-path ./proj --mode full --name bug_crlf
codebase-memory-mcp cli get_architecture --project bug_crlf
# node_labels: File, Module, Project, Branch (NO Method, NO Class)
# 2. Convert to LF, re-index — WORKS
sed -i 's/\r$//' proj/LearnTypeModel.cs # CRLF -> LF
codebase-memory-mcp cli index_repository --repo-path ./proj --mode full --name ok_lf
codebase-memory-mcp cli get_architecture --project ok_lf
# node_labels: Method, Class, Field, ... ✅Controlled experiment (single-file, isolated variables)
Same file, only one variable changed at a time:
| Line endings | /// doc comments |
Non-ASCII content | Result |
|---|---|---|---|
| CRLF | yes | yes (Chinese) | ❌ 0 Method, 0 Class (file tree only) |
| LF | yes | yes (Chinese) | ✅ Method=2, Class=1 |
| CRLF | removed | yes (Chinese) | ✅ Method=2, Class=1 |
| LF | no | yes (Chinese) | ✅ Method=2, Class=1 |
Conclusion: the bug is triggered by the CRLF + /// doc comment combination. Non-ASCII (Chinese) is not a factor — it parses fine under LF.
Whole-project impact
Indexing the full fx_testmodule project (28 .cs files, all CRLF with /// comments):
| Version | nodes | edges | Method | Class |
|---|---|---|---|---|
| CRLF (original) | 73 | 72 | 0 ❌ | 0 |
| LF (converted, comments kept) | 748 | 1540 | 243 ✅ | 48 |
Expected behavior
CRLF is the line-ending default for Visual Studio / Windows .NET projects. The C# parser should handle CRLF + XML doc comments identically to LF. At minimum, a parse failure should surface in skipped[] or a warning rather than silently producing a degenerate file-tree-only graph.
Workaround
Convert .cs files to LF before indexing (in a mirror copy, not the source repo). This preserves all comments and non-ASCII content while restoring full extraction.
Additional notes
- The failure is silent (
skipped_count: 0,status: indexed) — hardest part of diagnosing was realizing extraction had failed at all. - Not related to the CJK repo_path issue (Windows: tree-sitter definitions pass fails on ALL files when repo_path contains non-ASCII (CJK / Cyrillic / Arabic / accented Latin / etc.) characters #636/[Bug] v0.9.0 regression: CJK repo_path still crashes despite #636 fix #973) — repo paths here are pure ASCII; the content is what triggers it.
- A previously-suspected "non-ASCII is the root cause" conclusion (from v0.8.1 era) turned out to be a confounded experiment: the "de-Chinese'd" sample also had CRLF→LF applied, so the real variable (line endings) was masked.
Activity
DeusData commentedon Jul 14, 2026
Thanks for the minimal CRLF-versus-LF control case. This is a high-priority 0.9.1-rc parsing bug because indexing reports success while silently dropping the C# structure. The regression should keep the source bytes identical apart from line endings and cover XML doc comments plus a CRLF control without them, so the failing interaction is pinned precisely.
DeusData commentedon Jul 15, 2026
Investigation update — I need one more piece from you to pin this, because it does not reproduce on macOS/Linux even with your exact file.
What I ruled out: I reconstructed your
LearnTypeModel.csbyte-for-byte (UTF-8 with BOM, CRLF, the nested<para>/<see cref>XML doc with</>entities and Chinese text) and indexed it. On macOS it extracts the full structure (Class + both methods) under both LF and CRLF, with and without the BOM. So the bug isn't in the grammar's handling of CRLF+doc-comments per se.I also traced all three source-read paths (
read_filein pass_parallel.c / pass_definitions.c / pass_calls.c): every one opens"rb"(binary) and uses the actual bytes read, not the stat size — so the obvious theory (Windows text-modefreadtranslating CRLF→LF and truncating the buffer) is ruled out; the bytes handed to tree-sitter are identical across platforms.That means it's something specific to the Windows release binary / environment that I can't see from here. Three things would pin it — could you:
CBM_PROFILE=1 codebase-memory-mcp cli index_repository '{...}'and share the worker log — specifically whether the C# file shows a parse error /parse_partialregion.///doc comments removed but CRLF kept? And does a hexdump of the first ~16 bytes confirm the BOM (EF BB BF) + CRLF (0D 0A)?Labeling awaiting-reporter for that data. I'm not going to guess-fix a Windows-only failure I can't reproduce — but with the profile output I can likely pin it fast. Thanks for the clean LF-vs-CRLF control; that part is unambiguous.
github-actions commentedon Jul 15, 2026
Thanks for the report! To move this forward we need a bit more so we can reproduce it ourselves:
codebase-memory-mcp --versionyou're onOnce that's here we'll pick it straight back up. Heads-up: issues left
awaiting-reporterare automatically closed after a few weeks of silence, but a comment reopens the door anytime.github-actions commentedon Aug 6, 2026
This issue has been waiting on more information for 21 days (a version, exact steps, or a public repro), so it's now marked
stale. It will not be closed automatically — a maintainer reviews stale issues by hand. Adding a comment with the details clears the label and puts it straight back in the queue. We're happy to pick it back up the moment we can reproduce it.DeusData commentedon Sep 25, 2026
Thank you, @FIBlood, for the very clean controlled experiment. The CRLF vs LF table, with everything else held fixed, is exactly how to isolate this. Since it only shows on Windows, we'll run your exact file on our Windows test machine ourselves instead of waiting on you. If you have a moment, a retest on v0.11.0 with the original CRLF file would still help a lot: does
get_file_outlineonLearnTypeModel.csshow the class and its methods? Thanks for your patience!github-actions commentedon Oct 19, 2026
This issue has been waiting on more information for 21 days (a version, exact steps, or a public repro), so it's now marked
stale. It will not be closed automatically — a maintainer reviews stale issues by hand. Adding a comment with the details clears the label and puts it straight back in the queue. We're happy to pick it back up the moment we can reproduce it.