Skip to content

[finding] Two objectql engine test fixtures build aggregations: [{ func: … }] behind an as any — the declared key is function, so the aggregation they construct is silently dropped #8112

Description

@os-zhuang

Found while implementing #7809 (PR #8106). Not fixed there — out of scope, filed unassigned.

What

Two engine test fixtures pass an aggregation spelled func:

  • packages/objectql/src/engine-count-read-filter.test.ts:136
  • packages/objectql/src/engine-filter-tokens.test.ts:163

both as aggregations: [{ func: 'count', field: 'id', alias: 'n' }].

The declared key is function. EngineAggregateOptions's aggregation member is { function: 'count' | 'sum' | 'min' | 'max' | 'avg' | 'count_distinct'; alias: string; field?: string; … }. Confirmed by compiling the file: error TS2353: Object literal may only specify known properties, and 'func' does not exist in type '{ function: …; alias: string; … }'.

Both call sites erase the options bag with as any, which is the only reason the wrong spelling compiles. The aggregation schemas are not .strict(), so func is dropped, never rejected — the exact #4674 shape the query-options/no-any-erasure rule exists to prevent.

Severity: low, and stated narrowly

Neither test is currently wrong in its verdict. Both assert on where propagation (and groupBy), and both drive a driver double that records the AST without validating it, so the malformed aggregations member is inert. Nothing is green that should be red today.

What it costs is accuracy of the fixture: the input these tests construct is not the input they read as constructing, and the next person to extend either one — to assert something about the aggregation — inherits a spec that the engine would drop. It is also a live example for AI authors of the alias that #6321 concluded had no writer outside the drivers' own fixtures.

Relationship to #6321 (closed)

#6321 recorded agg.func as a lenient alias the spec never declared, whose only writers were the drivers' own fixtures. These two are engine fixtures, so they are outside that census — a small correction to it rather than a duplicate. The deliberate off-contract uses in driver-turso/src/remote-transport-undeclared-aggregate-keys.test.ts and driver-sql/src/sql-driver-aggregate-undeclared-keys.test.ts are not part of this finding: they are named for what they do, route through an offContract(…) helper, and are testing precisely that undeclared keys are handled.

Suggested fix

Re-spell both as function: and drop the as any on the options argument — the signatures already infer. Note that dropping the erasure is what makes the mistake visible at all, so the two halves belong in the same edit. Doing so also lowers the check:query-options-erasure test-surface count, which is a decrease-only ratchet, so it needs --update and a committed baseline in the same PR.

How it was found

Typing the four read-options bags in a new objectql test (to fix a check:query-options-erasure growth honestly rather than by baselining) made tsc reject the same func spelling that had been copied from engine-count-read-filter.test.ts. The copy was caught; the source was not touched.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions