Repository navigation
extra_extensions silently ignores jinja2 — Flask/Jinja .html templates cannot use the vendored Jinja2 grammar #2563
Description
Version
codebase-memory-mcp 0.11.0 (build 7edcd3807ebc)
Platform
Windows (x64)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
ui
What happened, and what did you expect?
extra_extensions cannot select the built-in jinja2 language, and it fails silently.
docs/CONFIGURATION.md §1 documents extra_extensions as a way to map file extensions to built-in languages, noting that unknown language names are skipped. jinja2 is a built-in language — it has a display name (src/discover/language.c:857), a vendored grammar (internal/cbm/grammar_jinja2.c, registered at internal/cbm/lang_specs.c:2357) and three native extensions (.j2 / .jinja / .jinja2, src/discover/language.c:464,470,473).
It still cannot be referenced from config, because the reverse lookup table used to parse the value has no entry for it:
lang_from_string()consultsLANG_NAME_TABLE(src/discover/userconfig.c:72-150) — 75 entries, nojinja2.- So
lang_from_string("jinja2")returnsCBM_LANG_COUNT. parse_extra_extensions()then drops the entry (src/discover/userconfig.c:229-233).
The failure is completely silent: the userconfig.unknown_lang warning at src/discover/userconfig.c:231 never appears on stderr or in any log, so the config looks like it took effect while doing nothing at all.
Expected: either the mapping applies, or the documented warning fires.
Actual: silent no-op.
Suggested fix
- Add
jinja2toLANG_NAME_TABLEsoextra_extensionscan select a language that already exists in the build. - Actually emit the
userconfig.unknown_langwarning — a documented config that silently does nothing is worse than one that is rejected with a message.
Related
- Twig (.twig) templates not extracted — add native Twig parser with Twig→PHP bridge #1891 Twig templates not extracted (open) — same family; Twig and Jinja2 share almost all surface syntax.
- Extract dbt {% macro %} definitions from raw .sql models #575 dbt
{% macro %}extraction (closed, merged) — precedent that Jinja macro extraction is in scope. - Blade (.blade.php) files not covered by code discovery gate / indexer #258 Blade
.blade.phpdiscovery gap (closed).
Reproduction
Dummy snippet only, no proprietary code.
1. Code
mkdir -p /tmp/jinja-probe && cd /tmp/jinja-probe
cat > a.html <<'EOF'
{% macro money_cell(amount) %}{{ amount }}{% endmacro %}
{% include "partials/_footer.html" %}
<script>
function initForm() { return 1; }
function submitForm() { initForm(); }
</script>
EOF
cp a.html b.jinja2
cp a.html c.htm
cat > .codebase-memory.json <<'EOF'
{ "extra_extensions": { ".html": "jinja2", ".htm": "markdown" } }
EOF2. Command
codebase-memory-mcp cli index_repository '{"repo_path":"/tmp/jinja-probe","mode":"full"}'3. Result vs expected
Querying the resulting store (SELECT file_path, label, name FROM nodes):
| file | config says | grammar actually used | extracted nodes |
|---|---|---|---|
a.html |
→ jinja2 |
HTML (unchanged) | File, Module, Function initForm, Function submitForm |
b.jinja2 |
native jinja2 | jinja2 | File, File, Module — no function, no macro, no include |
c.htm |
→ markdown (control) |
markdown | File, Module — both functions gone |
c.htm is the control: it proves the config file is read, and that a known-good language name really does change the grammar used. a.html proves jinja2 is rejected. Same result with {".html": "liquid"}.
Expected: a.html should lose its embedded-JS functions the same way c.htm does.
Actual: a.html is byte-for-byte unchanged from the default HTML behaviour.
Logs
level=warn msg=mem.allocator.preloading_completed still_preloading=false detail=...
warning: passing raw JSON to 'cli index_repository' is deprecated and will be removed in a future release; ...
No userconfig.unknown_lang, no userconfig.bad_extra_extensions — nothing at all. The only signal a user gets that the mapping was rejected is that the graph did not change.
Project scale
Flask+Jinja repo, 287 .html templates: 1,967 / 7,938 nodes (24.8%) are template-related, incl. 1,108 Function nodes from inline <script>. Jinja macros/includes/extends extracted: 0. render_template() edges: 0.
Confirmations
- I searched existing issues and this is not a duplicate. (Twig (.twig) templates not extracted — add native Twig parser with Twig→PHP bridge #1891 covers Twig, not Jinja2; Extract dbt {% macro %} definitions from raw .sql models #575 covers dbt
.sqlmodels, not web templates; neither covers theextra_extensionsname-table gap.) - My reproduction uses shareable code (a dummy snippet), not proprietary code.
Activity