I have:
If you have encountered an actual issue:
Bug
get_symbols_overview, find_symbol, and find_referencing_symbols fail for every file under a source directory named coverage/ (e.g. src/routes/coverage/):
ValueError: Cannot extract symbols from file src/routes/coverage/<x>.ts. Active languages: ['typescript_vts']
The same file extracts correctly at any path whose segments don't include coverage. find_referencing_symbols on symbols defined under such a directory silently returns nothing, even when references obviously exist elsewhere.
Root cause
The TypeScript language servers hard-ignore any directory named coverage by bare name, in is_ignored_dirname:
src/solidlsp/language_servers/typescript_language_server.py
src/solidlsp/language_servers/vts_language_server.py
@override
def is_ignored_dirname(self, dirname: str) -> bool:
return super().is_ignored_dirname(dirname) or dirname in [
"node_modules", "dist", "build", "coverage",
]
The intent is to skip Jest/nyc coverage-report output. But the match is on bare dirname, so it also excludes legitimate source directories named coverage — an ordinary domain/module name (in our case a REST API resource: src/routes/coverage/).
This is the same class of over-broad hardcoded exclusion narrowed for dot-dirs in #1187 / #1203 ("only hardcode what's universal; rely on gitignore for generated dirs"), and discussed for PHP vendor in #731 / #743.
Why it's confusing to diagnose
The exclusion is applied at the language-server layer (is_ignored_dirname), independent of Serena's project-level ignore machinery. So:
git check-ignore src/routes/coverage/x.ts → not ignored
serena project is_ignored_path src/routes/coverage/x.ts → reports not ignored
serena project index still counts the files
…yet symbol extraction refuses the file. There is no config hook feeding is_ignored_dirname (confirmed in ls.py / settings.py); the only analogous per-language override is PHP's ls_specific_settings.intelephense.ignore_vendor (added in #743). A user cannot un-ignore the directory via .serena/project.yml.
Re-indexing does not help, and is a tempting dead end. serena project index is incremental and treats the files as already cached (the run completes at thousands/sec — effectively a no-op), so it looks like it "did nothing wrong." Even a forced re-extraction wouldn't matter: the exclusion happens at symbol-extraction time in the language server, not in the index cache. We initially chased a stale-cache theory and rebuilt the cache repeatedly before realizing the directory was never being extracted in the first place.
Reproduction
- In any TypeScript project, create a source directory named
coverage with a .ts file containing a top-level symbol — src/coverage/thing.ts:
export function thing() { return 1; }
…and a sibling outside it, src/elsewhere.ts:
export function elsewhere() { return 2; }
- Ensure
coverage is NOT in .gitignore or ignored_paths (it isn't, for a source dir).
get_symbols_overview on src/elsewhere.ts → returns elsewhere. ✅
get_symbols_overview on src/coverage/thing.ts → ValueError: Cannot extract symbols .... ❌
Confirming it's the path segment, not the file (airtight isolation)
Copy the failing file to two un-indexed locations — one whose path contains a coverage/ segment, one neutral — and call get_symbols_overview on each. Identical bytes; only the path differs. The coverage/-path copy fails, the neutral copy succeeds ⇒ the exclusion is keyed on the directory name, not file content. grep -rn '"coverage"' src/solidlsp/language_servers/ then points straight at the two is_ignored_dirname lists.
Expected behavior
Symbol tools should work on any non-gitignored source directory, including one named coverage. A real coverage-report directory is generated output and is essentially always gitignored, so gitignore already excludes it — the hardcoded entry is redundant for its intended purpose and harmful for source dirs (the reasoning accepted in #1203).
Proposed fix
Remove "coverage" from the hardcoded list in both TS language servers and rely on gitignore for real report dirs (consistent with #1203). node_modules / dist / build are left untouched to keep this a single logical change; dist / build are arguably the same class but far less likely to collide with source-directory names, so I've left that decision to maintainers. Happy to open a PR (linked).
Workaround (until a fix lands)
- Remove the
"coverage", entry from is_ignored_dirname in both typescript_language_server.py and vts_language_server.py in your installed solidlsp (site-packages). Wiped by uv tool upgrade serena-agent.
- Add the real report dir to
ignored_paths, root-anchored so it doesn't re-match nested source dirs:
ignored_paths:
- /coverage
- Stop the MCP server,
rm <project>/.serena/cache/typescript/*.pkl, re-run serena project index (now at real-extraction speed), reconnect.
Setup
- Serena: 1.5.3
- MCP client: Claude Code
- OS: macOS
- Language: TypeScript (vtsls /
typescript_vts)
- Project: closed-source; repro above is project-independent
I have:
.serena/project.ymlignore_vendor#743 PHPvendor;get_symbols_overviewandfind_symbolfail for files in dot-prefixed directories #1187 / Allow symbol operations in dot-prefixed directories #1203 / find_symbol fails on dot-directory files while get_symbols_overview succeeds #853 dot-dirs)If you have encountered an actual issue:
<uv invocation> serena project health-check— see note: our local install is already patched, so it no longer reproduces; diagnosis below used per-file CLI extraction + path-vs-content isolation insteadBug
get_symbols_overview,find_symbol, andfind_referencing_symbolsfail for every file under a source directory namedcoverage/(e.g.src/routes/coverage/):The same file extracts correctly at any path whose segments don't include
coverage.find_referencing_symbolson symbols defined under such a directory silently returns nothing, even when references obviously exist elsewhere.Root cause
The TypeScript language servers hard-ignore any directory named
coverageby bare name, inis_ignored_dirname:src/solidlsp/language_servers/typescript_language_server.pysrc/solidlsp/language_servers/vts_language_server.pyThe intent is to skip Jest/nyc coverage-report output. But the match is on bare dirname, so it also excludes legitimate source directories named
coverage— an ordinary domain/module name (in our case a REST API resource:src/routes/coverage/).This is the same class of over-broad hardcoded exclusion narrowed for dot-dirs in #1187 / #1203 ("only hardcode what's universal; rely on gitignore for generated dirs"), and discussed for PHP
vendorin #731 / #743.Why it's confusing to diagnose
The exclusion is applied at the language-server layer (
is_ignored_dirname), independent of Serena's project-level ignore machinery. So:git check-ignore src/routes/coverage/x.ts→ not ignoredserena project is_ignored_path src/routes/coverage/x.ts→ reports not ignoredserena project indexstill counts the files…yet symbol extraction refuses the file. There is no config hook feeding
is_ignored_dirname(confirmed inls.py/settings.py); the only analogous per-language override is PHP'sls_specific_settings.intelephense.ignore_vendor(added in #743). A user cannot un-ignore the directory via.serena/project.yml.Re-indexing does not help, and is a tempting dead end.
serena project indexis incremental and treats the files as already cached (the run completes at thousands/sec — effectively a no-op), so it looks like it "did nothing wrong." Even a forced re-extraction wouldn't matter: the exclusion happens at symbol-extraction time in the language server, not in the index cache. We initially chased a stale-cache theory and rebuilt the cache repeatedly before realizing the directory was never being extracted in the first place.Reproduction
coveragewith a.tsfile containing a top-level symbol —src/coverage/thing.ts:src/elsewhere.ts:coverageis NOT in.gitignoreorignored_paths(it isn't, for a source dir).get_symbols_overviewonsrc/elsewhere.ts→ returnselsewhere. ✅get_symbols_overviewonsrc/coverage/thing.ts→ValueError: Cannot extract symbols .... ❌Confirming it's the path segment, not the file (airtight isolation)
Copy the failing file to two un-indexed locations — one whose path contains a
coverage/segment, one neutral — and callget_symbols_overviewon each. Identical bytes; only the path differs. Thecoverage/-path copy fails, the neutral copy succeeds ⇒ the exclusion is keyed on the directory name, not file content.grep -rn '"coverage"' src/solidlsp/language_servers/then points straight at the twois_ignored_dirnamelists.Expected behavior
Symbol tools should work on any non-gitignored source directory, including one named
coverage. A real coverage-report directory is generated output and is essentially always gitignored, so gitignore already excludes it — the hardcoded entry is redundant for its intended purpose and harmful for source dirs (the reasoning accepted in #1203).Proposed fix
Remove
"coverage"from the hardcoded list in both TS language servers and rely on gitignore for real report dirs (consistent with #1203).node_modules/dist/buildare left untouched to keep this a single logical change;dist/buildare arguably the same class but far less likely to collide with source-directory names, so I've left that decision to maintainers. Happy to open a PR (linked).Workaround (until a fix lands)
"coverage",entry fromis_ignored_dirnamein bothtypescript_language_server.pyandvts_language_server.pyin your installedsolidlsp(site-packages). Wiped byuv tool upgrade serena-agent.ignored_paths, root-anchored so it doesn't re-match nested source dirs:rm <project>/.serena/cache/typescript/*.pkl, re-runserena project index(now at real-extraction speed), reconnect.Setup
typescript_vts)