Uh oh!
There was an error while loading. Please reload this page.
Fix 19 documentation links that 404, and correct the touched pages against the engine source - #57
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
GuanzhouSong
commented
Aug 3, 2026
Two findings of the same class as this PR, in files the diff does not touch — so they can't be left as inline comments. I re-derived your model against the live site before reviewing, and it holds: 1. |
f93cc46 to
10d7424Compare10d7424 to
bd51ebdComparebd51ebd to
cbb7945CompareThree distinct causes, all confirmed against the live site. Bare sibling links resolve one level too deep. documentdb.io serves pages with a trailing slash, 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: [insert](insert) on the find page resolves to .../find/insert, not .../insert. Ten links across find, delete, update, insert, and getMore were affected. getMore also needed a different depth for the aggregate link - ../aggregation/aggregate lands in query-and-write/aggregation/, which does not exist. /docs/api-reference does not exist; the reference is served at /docs/reference. Three links used the old path, one in postgres-api/functions.md and two in getting-started/mongo-shell- quickstart.md. The quickstart pair does not currently render - the site shadows that route with hardcoded content - but they go live the moment that override is removed, so they are fixed here too. The .md extension leaks into rendered links. Inline markdown links are not rewritten, so functions.md and %24bucket.md reach the browser verbatim. The $bucketauto links compounded both bugs - leaked extension and wrong depth. Also fixed, same class and found while checking: the Related Topics link in arithmetic-expression/index.md pointed at ../comparison/, but the directory is comparison-query. That file does not currently render either, since api-reference landing pages are generated. Targets carry a trailing slash so they resolve directly rather than through a 301. Every one of the 15 links was verified by resolving it against its rendered page URL and status-checking the result: all 200. Fixesdocumentdb/documentdb.github.io#126
…es against the engine source Follow-up to the previous commit on this branch, addressing review feedback. Link fixes ---------- Switch every corrected inline link to an absolute https://documentdb.io/docs/ target. The previous commit used site-relative forms such as ../insert/ and functions/. Those resolve on the rendered site but 404 in GitHub blob view and in editors, and for postgres-api/index.md and $bucketauto.md that traded a working source link (functions.md, ./%24bucket.md) for a broken one. No single relative form works on both surfaces - GitHub needs insert.md while the site needs ../insert/ - so absolute is the only target that resolves everywhere. This also matches the form commit 2415b71 used for the same class of fix. Fix two links of the same class that the earlier sweep missed: getting-started/python-setup.md:286 - [MongoDB Shell Guide](mongo-shell-quickstart.md) rendered raw and 404s live; the adjacent line 285 was fixed in 2415b71 while this one was left. readme.md:8 - [API Reference](api-reference/index.md) points at a file b6eb41a deleted; the landing page is generated and served at /docs/reference/. Add the trailing slash to the /docs/reference targets this branch introduces, so they resolve directly rather than through a 301, matching the stated style. Delete api-reference/operators/arithmetic-expression/index.md rather than repointing its Related Topics link. The file is never served - the folder URL returns the generated landing page, and /reference/operators/arithmetic-expression/index/ 404s - so the link fix was a no-op. readme.md says api-reference landing pages are generated and index.md files are unnecessary, and this was the last straggler b6eb41a missed when it removed the other twenty. Its "More content to be added" line was also stale: fifteen operators are documented in the folder. The landing description already lives in _metadata.description.md. Content corrections ------------------- Validated the touched pages against the DocumentDB engine and gateway sources. delete.md - deleteMany(filter, {"limit": 1}) was documented as the way to delete one of many matches. limit is a field of the wire-protocol deletes[] element, not a mongosh option, so it is ignored and every match is deleted (delete.c:889 takes the DeleteAllMatchingDocuments branch when limit is 0). Use deleteOne, and document the wire-protocol form separately. Also renumber the duplicated "Example 3" heading. getMore.md - the cursor id must be a BSON int64 (EnsureTopLevelFieldType(..., BSON_TYPE_INT64), bson_aggregation_pipeline.c:3101; the gateway requires as_i64 and rejects anything else with "getMore value should be an i64"), so both examples failed before executing. Wrap them in db.runCommand with NumberLong. An omitted batchSize does not fall back to a small default - aggregation_commands.c:2029 seeds INT_MAX, so the whole remaining cursor is returned, capped only by the 16 MB response limit. The 101 default applies to the first page of find/aggregate only (system_configs.c:152). Document maxTimeMS, which is accepted but was missing. insert.md - the ordered example was not valid JavaScript; the options object's braces were missing. ordered also already defaults to true (insert.c:294), which the parameter table did not say. $bucketauto.md - both worked examples showed output the engine cannot produce. Recomputed from bson_bucket_auto.c: example 1 buckets to {3,18} {18,60} {60,230} with averages 7.67 / 32.67 / 145, since a non-last bucket's max is the next bucket's first value (:780). Example 2 returns three buckets, not four - once a bucket's max is rounded up, following rows below it are absorbed (:732-755); the regression baseline shows the same collapse (bucket_auto.out:213-219: 100 values, buckets:5, POWERSOF2 -> 3 rows). Expand Behavior to cover the distribution rule, the shared boundaries, and the granularity rounding that causes the collapse. mongo-shell-quickstart.md - createUser used role: "readWrite", db: "mydb"; users.c:1448-1471 accepts only readAnyDatabase, readWriteAnyDatabase, and clusterAdmin, and users.c:1479 requires db "admin". createRole inheriting "readWrite" fails the same way. The index block created {email: 1} twice, so the second call collided on the auto-generated name email_1 and the unique index was silently never created (create_indexes.c:4512-4551). Note the documentdb.enableRoleCrud gate, which defaults to off (feature_flag_configs.c:49). postgres-api/index.md - PLAIN/EntraId authentication is rejected by the gateway: auth.rs:357 accepts only SCRAM-SHA-256 and MONGODB-OIDC, and ismaster.rs:69 advertises only SCRAM-SHA-256. MONGODB-OIDC is not a substitute either - it calls documentdb_api_internal.authenticate_token (query_catalog.rs:593), which no SQL in the extensions defines. postgres-api/functions.md - documentdb_api_internal.create_index_background does not exist under that name or schema. The real function is documentdb_api.create_indexes_background(p_database_name text, p_index_spec bson, OUT retval bson, OUT ok boolean, OUT requests bson) (create_index_background--latest.sql:20). update_role is an unconditional error stub (roles.c:190-195). rolesInfo shipped in v0.108-0, not v0.106-0 (CHANGELOG.md:124), and role CRUD is gated behind documentdb.enableRoleCrud.
Second round of review follow-ups on this branch.
Regressions from the previous commit
------------------------------------
mongo-shell-quickstart.md moved the unique index off the colliding email_1
name and onto {username: 1}, but no sample document on the page has a
username field. A unique index is not sparse by default -
create_indexes.c:6282-6293 sets generateNotFoundTerm for the non-sparse case -
so every document missing the path shares one "not found" term and the build
fails on the second one. Traded a name collision for a duplicate key
violation. Index the plain single-field example on name instead, leaving
{email: 1} free for the unique index: three distinct key patterns, all fields
present in every sample document, no generated-name collision. Document the
sparse caveat too.
The role examples were left running against mydb, which the page selects at
line 57 and never leaves. roles.c:345 requires the admin database for
createRole, dropRole, and rolesInfo, and
DEFAULT_ENABLE_ROLES_ADMIN_DB_CHECK is true
(feature_flag_configs.c:57), so they fail on a stock build. createUser is not
affected - DEFAULT_ENABLE_USERS_ADMIN_DB_CHECK is false - so the page showed
user creation succeeding and role creation failing from what looks like the
same code. Add "use admin" and say which commands need it.
The prose added to explain the role examples described createUser's role
documents and then said createRole "inherits from the same set", which reads
as the same document form. roles.c:405-410 requires bare strings and rejects
anything else with "Invalid inherited from role name provided." The example
was already correct; the explanation was not. Also note that createRole
requires a privileges field even when empty.
The enableRoleCrud note told readers to turn on a GUC without saying how, on
a page whose entire audience is in mongosh, where it cannot be set. Give the
ALTER SYSTEM form and say it needs psql.
Cross-page reconciliation
-------------------------
getting-started/index.md:48 still advertised "SCRAM-SHA-256 and Plain" after
the previous commit corrected the same claim on postgres-api/index.md. The
two sentences share no wording, so fixing one did not surface the other.
vscode-extension-guide.md:241 and :247 create {email: 1} and then
{email: 1, unique} - the identical email_1 collision diagnosed and fixed in
the quickstart, left standing in a sibling guide. Index the plain example on
createdAt.
Remaining corrections
---------------------
getMore.md: the Syntax block still showed a bare "getMore: <cursor-id>", the
exact form the parameter list below it says is rejected. Show the runnable
db.runCommand/NumberLong shape. Example 1 said it "retrieves the next five
documents" while the batchSize bullet calls it a maximum; say "up to five",
and warn that a short batch does not mean the cursor is drained - callers
must loop until cursor.id is 0. Call the {"$numberLong": ...} form Extended
JSON rather than raw BSON, and say where the cursor id comes from.
insert.md:341 claimed insertedIds confirms the order documents were inserted.
It is keyed by input position and is identical under ordered: false, so it
confirms nothing about execution order.
functions.md: give the version that introduced the enableRoleCrud gate
(v0.108-0) so "supported since v0.106-0" one line above is not read as
meaning reachable since v0.106-0, and note the admin-database requirement.
$bucketauto.md: the remainder rule said the first n mod b buckets take one
extra. The absorb loop decrements the same counter
(state->actualRowsLimit++; if (state->remainder > 0) state->remainder--), so
granularity absorption consumes spares and the extras do not always land in
the earliest buckets. Invisible in both worked examples, where n mod b is 0.Third round of review follow-ups.
delete.md
---------
All four examples plus the wire-protocol snippet filtered on
"promotionEvents.discounts.discountPercentage": 21, a value that appears
nowhere in the sample document above them - its discounts are 7, 15, 8, 22,
19, 19, 20, 19, 17 and 23. Every one returned deletedCount 0, so the
deleteOne-vs-deleteMany distinction that Example 3 and the wire-protocol
section exist to demonstrate never actually demonstrated itself. Switch to 19,
which the sample document matches three times over. Example 1 also used an _id
(68471088-...) that is not the sample document's (0fcc0bf0-...); point it at
the real one.
Reorder so the destructive example comes last. Previously Example 1 was
deleteMany({}), which empties the collection, leaving a reader who works
through the page in order unable to tell whether a later zero count meant bad
filter syntax, an ignored limit, or an already-empty collection.
mongo-shell-quickstart.md
-------------------------
The vector index declared dimensions: 384 while the Vector Search example
queried the same path with a three-element vector, so running both in order
fails on a dimension mismatch. Since the two blocks are separated by the
Aggregation Pipelines section, the error is easy to misread as $search syntax.
Set the index to 3 to match the query, and note that real embeddings are much
wider so nobody takes 3 as a recommendation.
Fix the dangling lead-in above the role examples, left over from inserting the
GUC prerequisite between it and its code block.
URL spelling
------------
The previous commits added trailing slashes to the links they touched, which
left the repo spelling the same target two ways - /docs/reference/ in touched
files against /docs/reference in the rest - so a future change to the URL base
would need two patterns and would silently miss half the links with either
one. Normalize every https://documentdb.io/docs/ link to the trailing-slash
form. The remaining files are unchanged in substance; the slash only avoids a
301 on the way to the same page.
Verified: all 28 external links in the repository resolve, and every
documentdb.io/docs link returns 200 directly with no redirect.BSON_MAX_ALLOWED_SIZE bounds the accumulated batch (cursors.c:1059), while the wire message limit reported by hello is maxMessageSizeBytes at 48000000. Calling the 16 MB figure a maximum response size conflated the two. Also note in delete.md that the examples are independent, since Example 1 removes the sample document the later filters match.
PR documentdb#58 landed on main while this branch was open and rewrote postgres-api/functions.md against v0.114-0. Its version supersedes this branch's edits to that file, including on one point where it is right and this branch was wrong: create_indexes_background does not wait for builds to finish. The SQL COMMENT ON says it does, which is where the earlier claim here came from, but the C implementation runs one SPI query and returns. Took documentdb#58's file wholesale during the rebase. Three things it did not cover are restored on top of it: The API Reference link at the bottom of the page is back to https://documentdb.io/docs/api-reference, which 404s - documentdb#58 branched from before this PR's fix, so the rewrite reintroduced it. This is the same cause 2 the PR documents. update_role is still described as "Updates an existing role's privileges or inherited roles." Its body is a bare ereport(ERROR) (roles.c:190-195) with no EnableRoleCrud guard, so every call raises regardless of spec or flag. Neither documentdb.enableRoleCrud nor documentdb.enableRolesAdminDBCheck was mentioned, so the page read as though the role functions work out of the box when the first is off by default and the second is on. configuration.md gains both flags. They do not belong in the existing off-by-default table, whose preamble scopes it to flags that fail silently - these raise - so they get their own subsection. Defaults confirmed at feature_flag_configs.c:49, 57 and 53.
0a95d4c to
99353cbCompareSeventeen links across six pages point at relative .md paths and every one of them 404s. On $search the link to $vectorSearch renders as href="./%24vectorsearch.md", which resolves against the page's own directory - documentdb.io serves these with a trailing slash - and lands at /operators/aggregation/$search/%24vectorsearch.md. Wrong depth and a leaked extension, the two failure modes #57 catalogued, in the same href. They were introduced together. $vectorSearch, $project, $limit and $graphLookup arrived in #59, $search in #64 following the convention it found on the page next to it, and $meta links back to $vectorSearch the same way. None of them render, so the pages read as cross-linked while every cross-link is dead. Rewritten to the absolute form the rest of the reference already uses - https://documentdb.io/docs/reference/operators/aggregation/%24bucket/ - which is what #57 settled on for exactly this reason: it does not depend on how the site resolves a relative path, and it survives a page moving between directories. All thirteen distinct targets were requested against the live site and return 200, and no relative .md link remains anywhere in the repository.
Fixesdocumentdb/documentdb.github.io#126.
19 rendered documentation links resolve to a 404. Four distinct causes, all confirmed against the live site. Verifying the affected pages against the DocumentDB engine and gateway sources also turned up a number of factual errors and unrunnable examples on those same pages — see Content corrections.
Cause 1 — bare sibling links resolve one level too deep (10 links)
documentdb.io serves pages with a trailing slash, 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 is invisible to source review — it only reproduces against the exported URLs.
Affected:
find.md(2),delete.md(2),update.md(2),insert.md(2),getMore.md(2).Cause 2 —
/docs/api-referencedoes not exist (3 links)The reference is served at
/docs/reference. Fixed inpostgres-api/functions.mdandgetting-started/mongo-shell-quickstart.md(2).The quickstart pair does not currently render — documentdb.io shadows that route with hardcoded content that already uses the correct path — so those two are latent rather than live. They go live the moment the override is removed, so they are fixed here too.
Cause 3 —
.mdextension leaks into rendered links (5 links)Inline markdown links are not rewritten, so the extension reaches the browser verbatim:
postgres-api/index.md—[Functions](functions.md)->/docs/postgres-api/functions.mdapi-reference/operators/aggregation/$bucketauto.md(3) —[`$bucket`](./%24bucket.md)->.../$bucketauto/%24bucket.mdgetting-started/python-setup.md:286—[MongoDB Shell Guide](mongo-shell-quickstart.md)->/docs/getting-started/python-setup/mongo-shell-quickstart.mdThe
$bucketautoandpython-setuplinks compounded two bugs: leaked extension and wrong depth.Note
postgres-api/navigation.ymlalso useslink: functions.md, but that is correct and untouched — the nav pipeline strips the extension and rendershref="/docs/postgres-api/functions/". Only the raw markdown renderer leaves it in.Cause 4 — target no longer exists (1 link)
readme.md:8linked toapi-reference/index.md, which commit b6eb41a deleted when it made the api-reference landing pages generated. Repointed at the served location.Why absolute URLs
Every corrected link uses an absolute
https://documentdb.io/docs/...target rather than a site-relative one.There is no relative form that works on both surfaces. Rendered on documentdb.io,
find.mdneeds../insert/; viewed as source on GitHub or in an editor, it needsinsert.md. Picking either one breaks the other. Two of these links —postgres-api/index.md'sfunctions.mdand$bucketauto.md's./%24bucket.md— currently work in source view, so a relative site-only fix would have traded a working link for a broken one:Absolute targets resolve on both, and match the form commit 2415b71 already used for this class of fix.
Every
https://documentdb.io/docs/link in the repository is normalized to carry a trailing slash, so it resolves directly instead of through a 301. Before this, 20 of 21 such links omitted it while the corrected ones carried it, leaving the same target spelled two ways — a later change to the URL base would have needed two patterns and silently missed half the links with either one.Also removed
api-reference/operators/arithmetic-expression/index.mdis deleted rather than having itsRelated Topicslink repointed.The file is never served — the folder URL returns the generated landing page, which contains none of this file's content, and
/docs/reference/operators/arithmetic-expression/index/404s — so fixing the link inside it changes nothing.readme.md:20states that api-reference landing pages are generated andindex.mdfiles are unnecessary, and this was the last straggler b6eb41a missed when it removed the other twenty. Its "More content to be added as operators are documented" line was stale besides: fifteen operators are documented in that folder. The landing-page description already lives in_metadata.description.md.Content corrections
Validating the touched pages against the engine surfaced defects more severe than the links. Each is cited to the source that governs it.
delete.mddeleteMany(filter, {"limit": 1})was documented as the way to delete one of many matches.limitis a field of the wire-protocoldeletes[]element, not a mongosh option, so it is ignored and every match is deleted (delete.c:889takes theDeleteAllMatchingDocumentsbranch whenlimitis 0). Now usesdeleteOne, with the wire-protocol form documented separately. Every example also filtered ondiscountPercentage: 21, a value absent from the sample document, so all of them returneddeletedCount: 0and thedeleteOne/deleteManydistinction never demonstrated itself; switched to19, which the sample matches three times. The duplicated "Example 3" heading is renumbered and the destructivedeleteMany({})moved last.getMore.mdbson_aggregation_pipeline.c:3101; the gateway requiresas_i64()and rejects anything else withgetMore value should be an i64), so both examples failed type validation before executing. Now wrapped indb.runCommandwithNumberLong. An omittedbatchSizedoes not fall back to a small default —aggregation_commands.c:2029seedsINT_MAX, so the whole remaining cursor is returned, bounded by the 16 MB accumulated-batch cap (cursors.c:1059). The 101 default applies to the first page offind/aggregateonly (system_configs.c:152). AddsmaxTimeMS, and a warning that a short batch does not mean the cursor is drained.insert.mdorderedalready defaults totrue(insert.c:294), which the parameter table did not say. The caption also claimedinsertedIdsconfirms insertion order; it is keyed by input position and is identical underordered: false.$bucketauto.mdbson_bucket_auto.c: example 1 buckets to{3,18} {18,60} {60,230}, since a non-last bucket'smaxis the next bucket's first value (:780). Example 2 returns three buckets, not four — once a bucket'smaxis rounded up, following rows below it are absorbed (:732-755); the regression baseline shows the same collapse (bucket_auto.out:213-219— 100 values,buckets:5,POWERSOF2-> 3 rows). Behavior section expanded to cover the distribution rule, the shared boundaries, and the granularity rounding that causes the collapse.mongo-shell-quickstart.mdcreateUserusedrole: "readWrite", db: "mydb";users.c:1448-1471accepts onlyreadAnyDatabase,readWriteAnyDatabase, andclusterAdmin, andusers.c:1479requiresdb: "admin".createRoletakes bare role names, not documents (roles.c:405-410), and must run againstadmin(roles.c:345, on by default). The index block created{email: 1}twice, colliding on the generated nameemail_1so the unique index was silently never created (create_indexes.c:4512-4551). The vector index declareddimensions: 384while the search example queried the same path with a 3-element vector. Adds thedocumentdb.enableRoleCrudprerequisite with theALTER SYSTEMform, since it cannot be set frommongosh.postgres-api/index.mdauth.rs:357accepts only SCRAM-SHA-256 and MONGODB-OIDC, andismaster.rs:69advertises only SCRAM-SHA-256. MONGODB-OIDC is not a usable substitute either — it callsdocumentdb_api_internal.authenticate_token(query_catalog.rs:593), which no SQL in the extensions defines.getting-started/index.md:48carried the same claim in different words and is corrected too.postgres-api/functions.mdcreate_indexes_backgrounddoes not wait for builds to finish; the SQLCOMMENT ONsays it does, the C implementation does not). Three corrections are restored on top: the/docs/api-referencelink, which #58 reintroduced by branching from before this fix;update_role, still described as working when its body is a bareereport(ERROR)(roles.c:190-195); and the absence of any mention ofdocumentdb.enableRoleCrud(off by default) orenableRolesAdminDBCheck(on by default).postgres-api/configuration.mdVerification
Every
documentdb.iolink in the repository was extracted and status-checked. No 404s remain, and all 16 resolve directly with no redirect. The remaining external links were checked too; the only non-200 underHEADis the VS Marketplace URL, which rejectsHEADand returns 200 toGET.The only relative inline links left in the repository are the four in
readme.md, which is a GitHub-rendered file (confirmed not served at/docs/) and whose targets all exist.The original 14 links were found by crawling all 268 URLs in documentdb.io's
sitemap.xml, extracting every rendered in-sitehref, resolving each against its containing page, and status-checking: 302 unique targets, 15 broken. The 15th is an operator docs URL fixed separately in documentdb/documentdb.github.io#131. The five added since came from reviewing the touched pages directly —python-setup.md:286and thereadme.mdentry point were both missed by the crawl, the former because the earlier manual sweep stopped at the line above it.Suggested follow-up
A link-check step in CI over the exported site would catch causes 1–3. Source-grepping catches none of cause 1, and would also report the shadowed quickstart links as broken when they do not currently render. Checking source-view resolution as well would catch the case that motivated absolute URLs here.