Problem
packages/core/src/splitter/ast-splitter.ts requires every supported language's tree-sitter grammar unconditionally at module load time:
const JavaScript = require('tree-sitter-javascript');
const TypeScript = require('tree-sitter-typescript').typescript;
const Python = require('tree-sitter-python');
const Java = require('tree-sitter-java');
const Cpp = require('tree-sitter-cpp');
const Go = require('tree-sitter-go');
const Rust = require('tree-sitter-rust');
const CSharp = require('tree-sitter-c-sharp');
const Scala = require('tree-sitter-scala');
None of these are wrapped in try/catch, so if any single one fails to load — for any reason, on any platform — the whole MCP server process crashes on startup, for every user, regardless of what languages their codebase actually uses.
Concrete case that hit this
On macOS arm64 (Node 24), the darwin-arm64 prebuilt binaries for tree-sitter-cpp and tree-sitter-scala are unsigned (codesign -dv → "code object is not signed at all"), while every other language's darwin-arm64 prebuild (rust, java, go, python, typescript, javascript, c-sharp, the tree-sitter core package itself) is properly signed. dlopen refuses to load the unsigned binary and throws ERR_DLOPEN_FAILED ("code signature invalid"), which propagates as an uncaught exception and kills the process before the MCP server even starts — for a TypeScript/JavaScript-only codebase with zero C++/Scala files.
Error: dlopen(.../tree-sitter-cpp/prebuilds/darwin-arm64/tree-sitter-cpp.node, 0x0001):
tried: ... (code signature invalid in ... errno=85 ...)
Attempting to locally ad-hoc re-sign the binary (codesign --force -s -) also fails ("main executable failed strict validation"), suggesting the binary itself has some structural issue from its build/cross-compile pipeline, not just a missing signature.
Impact
- The server is a hard, unrecoverable crash for affected users — not a degraded/partial-functionality situation. No amount of
EMBEDDING_PROVIDER/ignorePatterns/etc. configuration works around it, since it never gets past module load.
- This is entirely disconnected from the user's actual codebase — a pure-TypeScript repo crashes just as hard as a C++ one, because every parser loads eagerly regardless of use.
- The specific unsigned-binary issue is arguably a bug in the upstream
tree-sitter-cpp/tree-sitter-scala packages (not something this repo controls directly), but the blast radius here is self-inflicted: any single broken language parser (this one, or a future one, on any platform) takes down the entire server for all languages.
Suggested fix
Make per-language grammar loading lazy and defensive — either:
require() each grammar inside a try/catch at first use (when a file of that extension is actually encountered), logging a warning and disabling AST-splitting for that language on failure, falling back to the langchain character-based splitter for those files; or
- At minimum, wrap the top-level requires in try/catch and only register the languages that loaded successfully in the extension→parser map, rather than requiring the whole module to fail.
Either would have let this codebase (no C++/Scala files) index successfully without ever touching the broken parsers.
Workaround we used locally: ad-hoc-patched the two packages' bindings/node/index.js to a no-op stub (module.exports = { nodeTypeInfo: {} }) since they're never invoked for a language absent from the codebase — but this obviously isn't something an end user should have to do to install and run the server.
Problem
packages/core/src/splitter/ast-splitter.tsrequires every supported language's tree-sitter grammar unconditionally at module load time:None of these are wrapped in try/catch, so if any single one fails to load — for any reason, on any platform — the whole MCP server process crashes on startup, for every user, regardless of what languages their codebase actually uses.
Concrete case that hit this
On macOS arm64 (Node 24), the
darwin-arm64prebuilt binaries fortree-sitter-cppandtree-sitter-scalaare unsigned (codesign -dv→ "code object is not signed at all"), while every other language'sdarwin-arm64prebuild (rust, java, go, python, typescript, javascript, c-sharp, thetree-sittercore package itself) is properly signed.dlopenrefuses to load the unsigned binary and throwsERR_DLOPEN_FAILED("code signature invalid"), which propagates as an uncaught exception and kills the process before the MCP server even starts — for a TypeScript/JavaScript-only codebase with zero C++/Scala files.Attempting to locally ad-hoc re-sign the binary (
codesign --force -s -) also fails ("main executable failed strict validation"), suggesting the binary itself has some structural issue from its build/cross-compile pipeline, not just a missing signature.Impact
EMBEDDING_PROVIDER/ignorePatterns/etc. configuration works around it, since it never gets past module load.tree-sitter-cpp/tree-sitter-scalapackages (not something this repo controls directly), but the blast radius here is self-inflicted: any single broken language parser (this one, or a future one, on any platform) takes down the entire server for all languages.Suggested fix
Make per-language grammar loading lazy and defensive — either:
require()each grammar inside a try/catch at first use (when a file of that extension is actually encountered), logging a warning and disabling AST-splitting for that language on failure, falling back to thelangchaincharacter-based splitter for those files; orEither would have let this codebase (no C++/Scala files) index successfully without ever touching the broken parsers.
Workaround we used locally: ad-hoc-patched the two packages'
bindings/node/index.jsto a no-op stub (module.exports = { nodeTypeInfo: {} }) since they're never invoked for a language absent from the codebase — but this obviously isn't something an end user should have to do to install and run the server.