14 rendered documentation links return 404 (15 link instances). Three distinct root causes.
Revised. The original version of this issue claimed 10 broken links and cited paths in this repo. Both were wrong: two of the claimed links never render, seven more broken links were missed, and the files needing the fix live in documentdb/docs, not here. Corrected throughout; see "Where the fix belongs".
Where the fix belongs
articles/ and reference/ are build artifacts, not source. Both are gitignored here and cloned from documentdb/docs at build time per content.config.json:
$ git check-ignore -v articles/postgres-api/functions.md reference/commands/query-and-write/find.md
.gitignore:13:articles/*/ articles/postgres-api/functions.md
.gitignore:10:/reference/ reference/commands/query-and-write/find.md
Every path below is given as documentdb/docs path (the editable source), with the built path in parentheses. Mapping comes from content.config.json: api-reference → reference, postgres-api → articles/postgres-api.
Cause 1 — /docs/api-reference does not exist (1 link)
The reference is served at /docs/reference. /docs/api-reference 404s.
documentdb/docs path | Line | Built path |
|---|
postgres-api/functions.md | 112 | articles/postgres-api/functions.md |
For more complete examples (cursors, aggregation, sharding) see the [API Reference](https://documentdb.io/docs/api-reference).
Fix:/docs/reference. Also worth making site-relative rather than an absolute documentdb.io URL.
Note on two links that look broken but aren't:getting-started/mongo-shell-quickstart.md lines 185 and 264 contain the same bad /docs/api-reference target, but never render. app/services/articleService.ts:1220-1232 shadows that route with hardcoded mongoShellQuickStartContent, which already uses the correct /docs/reference:
curl -s https://documentdb.io/docs/getting-started/mongo-shell-quickstart/ | grep -c api-reference
# 0
They are latent — they go live the moment the hardcoded override is removed — so they are still worth fixing upstream, but they are not currently broken.
Cause 2 — bare relative links resolve one level too deep (10 links)
Pages are served with a trailing slash (trailingSlash: true in next.config.ts), so per RFC 3986 the base for a relative link is the directory.../find/, and a bare target becomes a child of the current page:
/docs/reference/commands/query-and-write/find/ + insert
-> /docs/reference/commands/query-and-write/find/insert (404)
No link rewriting happens for inline markdown links, so this only reproduces against the exported URLs — it is invisible in source review.
All under documentdb/docs → api-reference/commands/query-and-write/ (built: reference/commands/query-and-write/):
| File | Line | Link | Resolves to |
|---|
find.md | 348 | [insert with DocumentDB](insert) | .../find/insert |
find.md | 349 | [update with DocumentDB](update) | .../find/update |
delete.md | 175 | [insert with DocumentDB](insert) | .../delete/insert |
delete.md | 176 | [update with DocumentDB](update) | .../delete/update |
update.md | 200 | [insert with DocumentDB](insert) | .../update/insert |
update.md | 201 | [delete with DocumentDB](delete) | .../update/delete |
insert.md | 355 | [update with DocumentDB](update) | .../insert/update |
insert.md | 356 | [find with DocumentDB](find) | .../insert/find |
getMore.md | 10 | [find](./find) | .../getMore/find |
getMore.md | 10 | [aggregate](../aggregation/aggregate) | .../query-and-write/aggregation/aggregate |
Fix:../insert, ../update, ../delete, ../find for the first nine.
The tenth needs a different depth — getMore.md's ../aggregation/aggregate lands in query-and-write/aggregation/, which doesn't exist. The correct target is /docs/reference/commands/aggregation/aggregate (200), i.e. ../../aggregation/aggregate.
Cause 3 — .md extension leaks into rendered links (3 links)
documentdb/docs path | Line(s) | Link | Resolves to |
|---|
postgres-api/index.md | 40 | [Functions](functions.md) | /docs/postgres-api/functions.md |
api-reference/operators/aggregation/$bucketauto.md | 10, 120 | [`$bucket`](./%24bucket.md) | .../$bucketauto/%24bucket.md |
api-reference/operators/aggregation/$bucketauto.md | 121 | [`$group`](./%24group.md) | .../$bucketauto/%24group.md |
The $bucketauto links compound both bugs — leaked extension and wrong relative depth.
Fix: drop the extension and fix the depth: ../%24bucket/, ../%24group/, and functions (or /docs/postgres-api/functions).
Only inline body links are affected. postgres-api/navigation.yml also uses link: functions.md, but the nav pipeline strips the extension and renders href="/docs/postgres-api/functions/" correctly — the raw markdown renderer does not.
Reproduce
foruin \
docs/api-reference \
docs/postgres-api/functions.md \
docs/reference/commands/query-and-write/find/insert \
docs/reference/commands/query-and-write/update/delete \
docs/reference/commands/query-and-write/insert/find \
docs/reference/commands/query-and-write/getMore/find \
docs/reference/commands/query-and-write/aggregation/aggregate
doprintf"%-62s ""$u"; curl -s -o /dev/null -w "%{http_code}\n""https://documentdb.io/$u";doneAll return 404. Control: https://documentdb.io/docs/reference → 200.
Validation
Numbers come from a full crawl, not a sample: all 268 URLs in sitemap.xml were fetched, every rendered in-site href extracted (RSC flight payloads stripped so unrendered boundaries don't produce false positives), resolved against its containing page, and status-checked. Result: 302 unique in-site link targets, 15 broken, 19 broken instances. Fourteen of those 15 belong to this issue; the remaining one is the operator docs URL tracked in #125.
Suggested follow-up
A link-check step in CI over the exported out/ directory would catch all three causes. Source-grepping does not — cause 2 only manifests after export, and the shadowed-route case above shows a grep can also report links that never render.
14 rendered documentation links return 404 (15 link instances). Three distinct root causes.
Where the fix belongs
articles/andreference/are build artifacts, not source. Both are gitignored here and cloned fromdocumentdb/docsat build time percontent.config.json:Every path below is given as
documentdb/docspath (the editable source), with the built path in parentheses. Mapping comes fromcontent.config.json:api-reference→reference,postgres-api→articles/postgres-api.Cause 1 —
/docs/api-referencedoes not exist (1 link)The reference is served at
/docs/reference./docs/api-reference404s.documentdb/docspathpostgres-api/functions.mdarticles/postgres-api/functions.mdFix:
/docs/reference. Also worth making site-relative rather than an absolutedocumentdb.ioURL.Note on two links that look broken but aren't:
getting-started/mongo-shell-quickstart.mdlines 185 and 264 contain the same bad/docs/api-referencetarget, but never render.app/services/articleService.ts:1220-1232shadows that route with hardcodedmongoShellQuickStartContent, which already uses the correct/docs/reference:They are latent — they go live the moment the hardcoded override is removed — so they are still worth fixing upstream, but they are not currently broken.
Cause 2 — bare relative links resolve one level too deep (10 links)
Pages are served with a trailing slash (
trailingSlash: trueinnext.config.ts), so per RFC 3986 the base for a relative link is the directory.../find/, and a bare target becomes a child of the current page:No link rewriting happens for inline markdown links, so this only reproduces against the exported URLs — it is invisible in source review.
All under
documentdb/docs→api-reference/commands/query-and-write/(built:reference/commands/query-and-write/):find.md[insert with DocumentDB](insert).../find/insertfind.md[update with DocumentDB](update).../find/updatedelete.md[insert with DocumentDB](insert).../delete/insertdelete.md[update with DocumentDB](update).../delete/updateupdate.md[insert with DocumentDB](insert).../update/insertupdate.md[delete with DocumentDB](delete).../update/deleteinsert.md[update with DocumentDB](update).../insert/updateinsert.md[find with DocumentDB](find).../insert/findgetMore.md[find](./find).../getMore/findgetMore.md[aggregate](../aggregation/aggregate).../query-and-write/aggregation/aggregateFix:
../insert,../update,../delete,../findfor the first nine.The tenth needs a different depth —
getMore.md's../aggregation/aggregatelands inquery-and-write/aggregation/, which doesn't exist. The correct target is/docs/reference/commands/aggregation/aggregate(200), i.e.../../aggregation/aggregate.Cause 3 —
.mdextension leaks into rendered links (3 links)documentdb/docspathpostgres-api/index.md[Functions](functions.md)/docs/postgres-api/functions.mdapi-reference/operators/aggregation/$bucketauto.md[`$bucket`](./%24bucket.md).../$bucketauto/%24bucket.mdapi-reference/operators/aggregation/$bucketauto.md[`$group`](./%24group.md).../$bucketauto/%24group.mdThe
$bucketautolinks compound both bugs — leaked extension and wrong relative depth.Fix: drop the extension and fix the depth:
../%24bucket/,../%24group/, andfunctions(or/docs/postgres-api/functions).Only inline body links are affected.
postgres-api/navigation.ymlalso useslink: functions.md, but the nav pipeline strips the extension and rendershref="/docs/postgres-api/functions/"correctly — the raw markdown renderer does not.Reproduce
All return
404. Control:https://documentdb.io/docs/reference→ 200.Validation
Numbers come from a full crawl, not a sample: all 268 URLs in
sitemap.xmlwere fetched, every rendered in-sitehrefextracted (RSC flight payloads stripped so unrendered boundaries don't produce false positives), resolved against its containing page, and status-checked. Result: 302 unique in-site link targets, 15 broken, 19 broken instances. Fourteen of those 15 belong to this issue; the remaining one is the operator docs URL tracked in #125.Suggested follow-up
A link-check step in CI over the exported
out/directory would catch all three causes. Source-grepping does not — cause 2 only manifests after export, and the shadowed-route case above shows a grep can also report links that never render.