Found while implementing #6401 (GroupByNode.alias on the SQL faces). Adjacent to it, not created by it. Filed unassigned, recording not claiming — driver-mongodb is inside the #5499 investment freeze.
The finding
GroupByNodeSchema declares a UNION: a bare field name, or a structured { field, dateGranularity?, alias? } node. driver-mongodb can only take the first half.
packages/drivers/driver-mongodb/src/mongodb-aggregation.ts:
groupBy?: string[]; // :38 — half of the declared union
...
if (opts.groupBy && opts.groupBy.length > 0) {
for (const field of opts.groupBy) {
groupId[field] = `$${field}`; // :66-69
}
}
...
for (const field of opts.groupBy) {
project[field] = `$_id.${field}`; // :85-88 — mirrored in $project
}
A structured node is an object in that loop. groupId[field] stringifies it, so the $group._id key becomes the literal "[object Object]" and its value the literal "$[object Object]" — a field path that matches nothing. The $project stage mirrors the same key.
So the aggregation does not refuse and does not throw: it returns rows grouped by a nonexistent field path, under a column named [object Object].
Why tsc never saw it
packages/drivers/driver-mongodb/src/mongodb-driver.ts:512 passes the value through an any cast:
groupBy: (query as any).groupBy,
so the declared GroupByNode[] union never meets that string[] annotation. The annotation is a restatement of the protocol that drifted from it — the same shape #6212 closed for driver-turso's remote transport, which read groupBy as string[] and died on "[object Object]" as an unsafe identifier. That one at least failed loudly; this one answers.
Scope note — this is NOT the alias divergence
#6401 converged the three SQL faces onto alias ?? field for the projected column. driver-mongodb is not a fourth face of that divergence: the alias is unreachable here rather than ignored, because the whole structured half of the union is. Fixing alias alone would not help — the node has to be destructured first.
Recorded as a measured DEBT row in scripts/check-driver-conformance.mjs (the driver-mongodb × AGGREGATION_CASES cell) by #6401, so the conformance matrix carries the verdict rather than an omission.
Relationship to #6814
#6814 is the count_distinct disagreement for the same frozen pair — a wrong NUMBER from a lowering that exists. This is a different defect: a declared SHAPE that has no lowering at all. Same package, same freeze, separate cells; filing separately so the freeze is lifted against a measured list rather than one line item.
Verdict
Read from the source; not executed — this package has no server-free aggregation suite for the cell, which is part of the debt (the real-mongod suites are opt-in since #5517, so whatever closes this needs a server-free half like mongodb-filter-logic-translation.test.ts has).
Not fixed here: #5499 freezes the package, and #6401's ruling kept mechanical alignment out of the enforce change on principle — a frozen driver gets an honest row or a mechanical alignment, never a flip.
Related: #6401, #6814, #6212, #5499, ADR-0049.
Generated by Claude Code
Found while implementing #6401 (
GroupByNode.aliason the SQL faces). Adjacent to it, not created by it. Filed unassigned, recording not claiming —driver-mongodbis inside the #5499 investment freeze.The finding
GroupByNodeSchemadeclares a UNION: a bare field name, or a structured{ field, dateGranularity?, alias? }node.driver-mongodbcan only take the first half.packages/drivers/driver-mongodb/src/mongodb-aggregation.ts:A structured node is an object in that loop.
groupId[field]stringifies it, so the$group._idkey becomes the literal"[object Object]"and its value the literal"$[object Object]"— a field path that matches nothing. The$projectstage mirrors the same key.So the aggregation does not refuse and does not throw: it returns rows grouped by a nonexistent field path, under a column named
[object Object].Why
tscnever saw itpackages/drivers/driver-mongodb/src/mongodb-driver.ts:512passes the value through ananycast:so the declared
GroupByNode[]union never meets thatstring[]annotation. The annotation is a restatement of the protocol that drifted from it — the same shape #6212 closed fordriver-turso's remote transport, which readgroupByasstring[]and died on"[object Object]"as an unsafe identifier. That one at least failed loudly; this one answers.Scope note — this is NOT the
aliasdivergence#6401 converged the three SQL faces onto
alias ?? fieldfor the projected column.driver-mongodbis not a fourth face of that divergence: the alias is unreachable here rather than ignored, because the whole structured half of the union is. Fixingaliasalone would not help — the node has to be destructured first.Recorded as a measured DEBT row in
scripts/check-driver-conformance.mjs(thedriver-mongodb×AGGREGATION_CASEScell) by #6401, so the conformance matrix carries the verdict rather than an omission.Relationship to #6814
#6814 is the
count_distinctdisagreement for the same frozen pair — a wrong NUMBER from a lowering that exists. This is a different defect: a declared SHAPE that has no lowering at all. Same package, same freeze, separate cells; filing separately so the freeze is lifted against a measured list rather than one line item.Verdict
Read from the source; not executed — this package has no server-free aggregation suite for the cell, which is part of the debt (the real-mongod suites are opt-in since #5517, so whatever closes this needs a server-free half like
mongodb-filter-logic-translation.test.tshas).Not fixed here: #5499 freezes the package, and #6401's ruling kept mechanical alignment out of the enforce change on principle — a frozen driver gets an honest row or a mechanical alignment, never a flip.
Related: #6401, #6814, #6212, #5499, ADR-0049.
Generated by Claude Code