fix(client): data.find 的 top/skip 按存在性发射,limit: 0 不再被静默丢弃 (#6485) - #6578
Merged
os-project-manager merged 1 commit intoAug 8, 2026
Merged
Conversation
两处 `find`(`ObjectStackClient.data.find` 与 `ScopedProjectClient.data.find`
的逐字节副本)都以**真值**判断发射分页参数,而其上方十行的 canonical
normalizer 早已按**存在性**判断(`if (v2.limit != null)`)。于是 `0` 通过了
normalizer,又被发射端丢掉。两处一并改为存在性判断。
`find('task', { limit: 0 })` 此前到达服务端时**完全没有 `top` 参数**。GET 列表
路由没有默认页大小,所以缺失 `top` 返回的是**全量**匹配集:请求「不要记录」的
调用方拿到了每一条记录,HTTP 200,无任何告警。
方向是先测后改,而非假定:REST 列表路由(`findData`)既不拒绝也不忽略 `top=0`,
它折叠为 `limit: 0` 转发给引擎;`SqlDriver.find`(默认 SQLite 数据源背后的驱动)
同样按存在性分页,语句带 `LIMIT 0`,返回零行。
`offset: 0` / `skip: 0` 同样被丢弃,但那半边是一致性修改、无行为后果——`skip=0`
本就是服务端默认值。改它是因为一个发射端不该对同一对参数持两套规则。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uFVNMmTxLpmfQYiuKM1Yx
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 14 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-project-manager
marked this pull request as ready for review
August 8, 2026 06:13
os-project-manager
deleted the
claude/issue-6485-find-pagination-presence
branch
August 8, 2026 06:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6485
两处
find(ObjectStackClient.data.find与ScopedProjectClient.data.find的逐字节副本)都以真值判断发射分页参数,而其上方十行的 canonical normalizer 早已按存在性判断(if (v2.limit != null))。于是0通过了 normalizer,又被发射端丢掉。两处一并改为!= null。行号漂移
卡片正文记的是
eb7613c上的:4224/:4225与:4908/:4909;两条分诊评论分别在b7d3be4读到:4104/:4105、:4778/:4779,在3a1d9c7读到:4225/:4909。本次在53ef05744上按内容定位,落点回到:4224/:4225与:4908/:4909—— 与卡片正文数字重合纯属巧合,中间三次读数各不相同。所以按 pattern 找,不要信任何一处记下的行号。前提复现(改动前,在
origin/main上量的)新增断言直接跑在未修复的源码上,6 条红:
{ limit: 0 }发出的是空查询串 —— 一个top参数都没有。服务端
top=0到底怎么处理:先测后改这半边是本卡的关键。客户端把
top=0发出去,只有在服务端真的认这个值时才算修好。三层都实测过,不是读代码推的:top=0的实测行为ObjectStackProtocolImplementation.findDatatop折叠进limit,Number('0')得 0,{ limit: 0 }原样转发给引擎;信封给出total: 0, hasMore: falseSqlDriver.find(默认文件型 SQLite 数据源背后的驱动,也是 Postgres/MySQL 部署用的那个)LIMIT 0,零行TursoRemoteTransportLIMIT ?绑 0,零行探针输出:
即派发单列的三种结局里的第一种:服务端返回零记录,修复如描述般正确。
顺带纠正卡片正文一处措辞:丢掉
top之后拿到的不是「服务端默认页大小」—— 这条 GET 列表路由没有默认页大小。实测no top一栏返回 3/3 全量。所以find('task', { limit: 0 })的旧行为是「要零条、给全部」,比「给一页」更糟。offset: 0/skip: 0:这半边是一致性修改,没有行为后果明说,不包装成 bug fix:
skip=0本就是服务端默认值,发不发这个参数请求含义相同。改它的理由只有一个 —— 一个发射端不该对同一对参数持两套规则。测试:结构上保证半边修复必红
复用 #6322 建立的
driveBoth表格 —— 同一组 options 同时驱动两份find,比对同一个期望查询串。新增 5 行表项({ limit: 0 }/{ offset: 0 }/{ top: 0 }/{ skip: 0 }/{ limit: 0, offset: 0 }),外加一条性质断言:{ limit: 0 }与{}在线上必须可区分(旧代码里两者都发空串,正是这个坍缩本身)。反向验证:先写下预测,再跑
origin/main)expect(direct)L1401expect(direct)L1401ScopedProjectClient一份expect(scoped)L1402第三行是本卡要的那条约束:只修一份,另一份的
scoped断言就红。6 条断言没有一条在两个方向都是绿的,所以没有需要从红计数里剔除的「不变量 pin」。门禁(真实输出,非声明)
pnpm --filter @objectstack/client test→Test Files 21 passed (21) / Tests 269 passed (269)pnpm --filter @objectstack/client typecheck→tsc --noEmit通过;check:test-typecheck: OK — 0 file(s) / 0 error(s)pnpm lint→ 无输出(干净)lint.yml枚举的全部check:*:37 条根级门禁 + 11 条 spec 门禁全 PASS,含check:query-options-erasure、check:route-envelope、check:error-code-casing、check:engine-double-contract、check:nul-bytesturbo run typecheck --filter='./packages/*' --filter='./packages/*/*' --filter='./apps/*'→120 successful, 120 totalcheck:i18n/check:i18n-coverage首轮报的是前置条件未满足(本 worktree 未构建 CLI),不是发现;补齐构建后两条均 PASS(12 config(s), 660 baselined, none new)grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'三个改动文件均无命中;check:nul-bytesOKChangeset
@objectstack/client: patch。判断依据:这是缺陷修复,不新增 API、不新增选项、不移除能力;行为变化只落在limit: 0/top: 0这一组此前返回明确错误答案的输入上。变更正文把 wire 行为变化写明,以便进入 release notes。范围外发现
InMemoryDriver.findapplieslimiton truthiness, solimit: 0returns every row — the #6485 defect one layer below the client #6577 —InMemoryDriver.find同样按真值判断limit,limit: 0返回全表(实测 3/3),与SqlDriver的零行结果相反。本卡文件面只限packages/client/src/index.ts,故按 Prime Directive chore: version packages #10 另开、未认领。该 issue 同时列出sql-driver自身两处窗口函数/explain 门、memory-analytics两处同形代码,以及 MongoDB「limit: 0即无限制」这一不应照同一方式修的边界。🤖 Generated with Claude Code
https://claude.ai/code/session_017uFVNMmTxLpmfQYiuKM1Yx
Generated by Claude Code