Problem
functions.json holds 516 function entries, but only 515 reference pages exist. The
missing one is INDEX.
scripts/gen-docs.mjs slugifies function names to [a-z0-9]+ with dashes, so INDEX →
index. That collides with the generated section index at
content/docs/reference/functions/index.mdx, which wins — the INDEX function page is never
written.
Impact (verified 2026-08-05)
https://docs.truecalc.app/reference/functions/index → 404
content/docs/industries/operations.mdx:126 links to /reference/functions/index — a broken
internal link on a published page
INDEX is half of the INDEX/MATCH idiom, and comparisons/vlookup-vs-xlookup-vs-index-match.mdx
exists — so the gap lands on one of the more prominent lookup topics
- The section index page itself renders "516 functions", which overstates what is actually
documented
Reproduce
node -e "
const fs=require('fs');
const j=JSON.parse(fs.readFileSync('<core>/functions.json','utf8'));
const files=new Set(fs.readdirSync('content/docs/reference/functions')
.filter(f=>f.endsWith('.mdx')&&f!=='index.mdx').map(f=>f.replace(/\.mdx$/,'')));
const slug=n=>n.toLowerCase().replace(/[^a-z0-9]+/g,'-');
console.log(j.map(f=>f.name).filter(n=>!files.has(slug(n))));
"
# => [ 'INDEX' ]
curl -s -o /dev/null -w '%{http_code}\n' https://docs.truecalc.app/reference/functions/index
# => 404
Suggested fix
Reserve route-colliding slugs in gen-docs.mjs. index is the only collision today, but the
rule should be general — any function name that slugifies to a reserved route needs a suffix
(e.g. index-function) with the section index linking to it under the plain INDEX label.
Worth adding a generation-time assertion that every functions.json entry produced a page, so a
future collision fails the build instead of silently dropping a function.
Acceptance criteria
Context
Found while adding a derive-don't-quote rule for function counts — the workspace had been
repeating a stale "484 functions" figure. Deriving the real number from functions.json is what
exposed the missing page.
Problem
functions.jsonholds 516 function entries, but only 515 reference pages exist. Themissing one is
INDEX.scripts/gen-docs.mjsslugifies function names to[a-z0-9]+with dashes, soINDEX→index. That collides with the generated section index atcontent/docs/reference/functions/index.mdx, which wins — theINDEXfunction page is neverwritten.
Impact (verified 2026-08-05)
https://docs.truecalc.app/reference/functions/index→ 404content/docs/industries/operations.mdx:126links to/reference/functions/index— a brokeninternal link on a published page
INDEXis half of the INDEX/MATCH idiom, andcomparisons/vlookup-vs-xlookup-vs-index-match.mdxexists — so the gap lands on one of the more prominent lookup topics
documented
Reproduce
Suggested fix
Reserve route-colliding slugs in
gen-docs.mjs.indexis the only collision today, but therule should be general — any function name that slugifies to a reserved route needs a suffix
(e.g.
index-function) with the section index linking to it under the plainINDEXlabel.Worth adding a generation-time assertion that every
functions.jsonentry produced a page, so afuture collision fails the build instead of silently dropping a function.
Acceptance criteria
INDEXand is reachable/reference/functionslinks to it under the labelINDEXindustries/operations.mdx:126resolves (no 404)gen-docsfails the build if anyfunctions.jsonentry yields no pageContext
Found while adding a derive-don't-quote rule for function counts — the workspace had been
repeating a stale "484 functions" figure. Deriving the real number from
functions.jsonis whatexposed the missing page.