graph: files in unsupported languages are silently absent — no warning at build, no signal at query
Thanks for mex — the scaffold and grounding halves have been solid for us. This is a
report about one failure mode in the graph half that is entirely silent, and I think the
silence is the bug rather than the language coverage.
Environment
mex-agent 0.7.3, node v26.0.0, macOS 26.6.2 arm64.
What happens
EXTENSION_MAP covers ten extensions — .ts .mts .cts .tsx .js .mjs .cjs .jsx .py .rs —
and SUPPORTED_SOURCE_GLOB is built from its keys. Every discovery path uses that glob:
discoverSourceFiles, liveUnindexedFiles, findChangedSourceFiles. A file with any
other extension is therefore invisible everywhere: not indexed, not a text fallback, not a
live-unindexed candidate.
Nothing reports this at any point.
Repro A — a repo with no supported files at all.
mkdir repro-go && cd repro-go && git init -q && mkdir .mex && echo '# Router' > .mex/ROUTER.md
cat > main.go <<'GO'
package main
type Server struct{ Addr string }
func NewServer(addr string) *Server { return &Server{Addr: addr} }
func (s *Server) Start() error { return nil }
GO
mex graph
Code graph built: 0 nodes, 0 edges across 0 files in 16ms → .mex/graph.db
Exit code 0. Then, from an agent's point of view:
| command |
output |
mex graph scope "server start" |
"status":"no-match", "evidenceStrength":"none", "warnings":[] |
mex graph query where-defined NewServer |
{"code":"TARGET_NOT_FOUND"} |
mex impact Server |
{"code":"TARGET_NOT_FOUND"} |
mex doctor |
✓ Drift 100/100, four green ticks |
TARGET_NOT_FOUND is the same answer a typo gets. An agent concludes the symbol does not
exist and moves on. The only distinguishing signal is health.indexedFiles: 0, which
appears in graph scope output and not in query or impact.
Repro B — a mixed repo, which is worse. This is the common case, not an exotic one:
any Svelte, Vue or Astro frontend. (Your own field report in #140 describes a
"Python backend + TS/Svelte frontend".)
mkdir repro-mixed && cd repro-mixed && git init -q && mkdir -p .mex src
echo '# Router' > .mex/ROUTER.md
cat > src/api.ts <<'TS'
export function fetchOrders(userId: string): Promise<string[]> {
return Promise.resolve([userId]);
}
TS
cat > src/OrderList.svelte <<'SV'
<script lang="ts">
import { fetchOrders } from './api';
export let userId: string;
export function refreshOrders() { return fetchOrders(userId); }
</script>
<ul>{userId}</ul>
SV
cat > src/Checkout.vue <<'VUE'
<script setup lang="ts">
function submitPayment(amount: number) { return amount * 100; }
</script>
<template><button @click="submitPayment(1)">Pay</button></template>
VUE
mex graph
mex graph query where-defined refreshOrders
mex graph query where-defined submitPayment
mex graph query where-defined fetchOrders
mex graph scope "orders refresh"
Code graph built: 2 nodes, 1 edges across 1 files in 160ms → .mex/graph.db
{"type":"error","code":"TARGET_NOT_FOUND","target":"refreshOrders"} # exists in the .svelte
{"type":"error","code":"TARGET_NOT_FOUND","target":"submitPayment"} # exists in the .vue
... "name":"fetchOrders","filePath":"src/api.ts" ... # the .ts resolves fine
and scope reports:
"indexedFiles":1 "textFallbackFiles":[] "warnings":[]
Three source files, one indexed. indexedFiles is non-zero, so even the single signal
from Repro A is gone. Two thirds of the codebase is missing from the graph and nothing
anywhere says so.
Why this matters more than coverage
The shipped CLAUDE.md template tells the agent to reach for the graph first and to treat
returned source as already read. When the graph is silently partial, the agent gets
TARGET_NOT_FOUND for symbols that exist and has no way to distinguish "not in this
codebase" from "this file type is not indexable". It then answers from a graph it believes
is complete.
Language coverage is tracked already (#93 for Go, #155 for C#) and I am not asking for
more extractors here. I am asking for the gap to be visible.
What would help
Any one of these would be enough:
mex graph reports skipped files: Code graph built: 2 nodes ... across 1 files (2 files skipped: unsupported extension), with the extension histogram behind --json.
filesIndexed gains a sibling filesSkipped in the JSON, so a setup script can gate on it.
query / impact include indexedFiles (or a coverage field) the way scope does, so TARGET_NOT_FOUND can be told apart from TARGET_NOT_INDEXABLE.
mex doctor warns when a repo contains source files that no extractor handles.
Happy to supply more repros or test a patch.
graph: files in unsupported languages are silently absent — no warning at build, no signal at queryThanks for mex — the scaffold and grounding halves have been solid for us. This is a
report about one failure mode in the graph half that is entirely silent, and I think the
silence is the bug rather than the language coverage.
Environment
mex-agent 0.7.3, node v26.0.0, macOS 26.6.2 arm64.
What happens
EXTENSION_MAPcovers ten extensions —.ts .mts .cts .tsx .js .mjs .cjs .jsx .py .rs—and
SUPPORTED_SOURCE_GLOBis built from its keys. Every discovery path uses that glob:discoverSourceFiles,liveUnindexedFiles,findChangedSourceFiles. A file with anyother extension is therefore invisible everywhere: not indexed, not a text fallback, not a
live-unindexed candidate.
Nothing reports this at any point.
Repro A — a repo with no supported files at all.
Exit code 0. Then, from an agent's point of view:
mex graph scope "server start""status":"no-match","evidenceStrength":"none","warnings":[]mex graph query where-defined NewServer{"code":"TARGET_NOT_FOUND"}mex impact Server{"code":"TARGET_NOT_FOUND"}mex doctor✓ Drift 100/100, four green ticksTARGET_NOT_FOUNDis the same answer a typo gets. An agent concludes the symbol does notexist and moves on. The only distinguishing signal is
health.indexedFiles: 0, whichappears in
graph scopeoutput and not inqueryorimpact.Repro B — a mixed repo, which is worse. This is the common case, not an exotic one:
any Svelte, Vue or Astro frontend. (Your own field report in #140 describes a
"Python backend + TS/Svelte frontend".)
and scope reports:
Three source files, one indexed.
indexedFilesis non-zero, so even the single signalfrom Repro A is gone. Two thirds of the codebase is missing from the graph and nothing
anywhere says so.
Why this matters more than coverage
The shipped
CLAUDE.mdtemplate tells the agent to reach for the graph first and to treatreturned source as already read. When the graph is silently partial, the agent gets
TARGET_NOT_FOUNDfor symbols that exist and has no way to distinguish "not in thiscodebase" from "this file type is not indexable". It then answers from a graph it believes
is complete.
Language coverage is tracked already (#93 for Go, #155 for C#) and I am not asking for
more extractors here. I am asking for the gap to be visible.
What would help
Any one of these would be enough:
mex graphreports skipped files:Code graph built: 2 nodes ... across 1 files (2 files skipped: unsupported extension), with the extension histogram behind--json.filesIndexedgains a siblingfilesSkippedin the JSON, so a setup script can gate on it.query/impactincludeindexedFiles(or acoveragefield) the wayscopedoes, soTARGET_NOT_FOUNDcan be told apart fromTARGET_NOT_INDEXABLE.mex doctorwarns when a repo contains source files that no extractor handles.Happy to supply more repros or test a patch.