Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

/installations and /audiences reject a find sent as POST + _method=GET with "Invalid key name: 0"

未关闭 适合新手
#10,626 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
半天
新手友好度
65/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
javascript, nodejs
领域
api, backend

调研方向

首先将 src/Routers/InstallationsRouter.js 和 src/Routers/AudiencesRouter.js 与 ClassesRouter.handleFind 进行比较,重点关注如何处理值来自请求体的字符串。对两个路由使用 curl method-override reproducer,并确认请求返回查询结果,而不是 Invalid key name: 0。

由索引模型根据 Issue 内容生成。

描述

New Issue Checklist
Issue Description

InstallationsRouter.handleFind and AudiencesRouter.handleFind override ClassesRouter.handleFind but drop its string-where decoding step, so a query sent with the documented POST + _method=GET override fails on /installations and /audiences while the identical query succeeds on /classes/_Installation.

ClassesRouter.handleFind decodes a where that arrives in the request body as a JSON string:

if (typeof body.where === 'string') {
  try {
    body.where = JSON.parse(body.where);
  } catch {
    throw new Parse.Error(Parse.Error.INVALID_JSON, 'where parameter is not valid JSON');
  }
}

The two subclasses copy the body/options lines but not that block, so they only handle a where that arrives in the query string (decoded by ClassesRouter.JSONFromQuery). When the client uses the method override with an application/x-www-form-urlencoded body, body.where stays a string and is passed straight to rest.find. DatabaseController.validateQuery then runs Object.keys() over the string, walking it character by character, and the first index fails the key-name regex:

{"code":105,"error":"Invalid key name: 0"}

This is the same failure mode as the AggregateRouter pipeline handling that produced Invalid aggregate stage '0'.

The trigger is query size, not query shape. SDKs switch from GET to POST + _method=GET once the URL exceeds ~2 KB, so this only appears when an app queries /installations with a large enough constraint, for example an installationId $in list of roughly 41 or more ids. The same code path works for /users, /roles and /sessions, whose routers inherit ClassesRouter.handleFind unchanged.

Steps to reproduce

Any query long enough for the SDK to use the method override reproduces this. A minimal equivalent with curl:

# 1. POST + _method=GET against /installations -> error 105
curl -s -X POST \
  -H 'X-Parse-Application-Id: myAppId' \
  -H 'X-Parse-Master-Key: myMasterKey' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode '_method=GET' \
  --data-urlencode 'where={"installationId":{"$in":["af593bd0-cede-4b27-b0d0-1b48a025dc03"]}}' \
  --data-urlencode 'limit=100' \
  http://localhost:1337/parse/installations

# 2. Identical request against /classes/_Installation -> succeeds
curl -s -X POST \
  -H 'X-Parse-Application-Id: myAppId' \
  -H 'X-Parse-Master-Key: myMasterKey' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode '_method=GET' \
  --data-urlencode 'where={"installationId":{"$in":["af593bd0-cede-4b27-b0d0-1b48a025dc03"]}}' \
  --data-urlencode 'limit=100' \
  http://localhost:1337/parse/classes/_Installation

# 3. Same where as a GET query string against /installations -> succeeds
curl -s -G \
  -H 'X-Parse-Application-Id: myAppId' \
  -H 'X-Parse-Master-Key: myMasterKey' \
  --data-urlencode 'where={"installationId":{"$in":["af593bd0-cede-4b27-b0d0-1b48a025dc03"]}}' \
  http://localhost:1337/parse/installations

/audiences fails the same way.

Actual Outcome
1. {"code":105,"error":"Invalid key name: 0"}
2. {"results":[]}
3. {"results":[]}
Expected Outcome

All three return the query results. The method override is supported transport for a find, so /installations and /audiences should decode a string where from the body exactly as /classes/:className does.

Environment

Server

  • Parse Server version: 9.10.0 (also present on alpha at 9.10.1-alpha.6; src/Routers/InstallationsRouter.js and src/Routers/AudiencesRouter.js are unchanged there)
  • Operating system: macOS 15.5 (Docker, node:22 image)
  • Local or remote host: local

Database

  • System (MongoDB or Postgres): MongoDB
  • Database version: 7.0.31
  • Local or remote host: local

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): reproduced with curl; originally hit from the Ruby SDK
  • SDK version: parse-stack-next 5.7.0
Logs
error: Invalid key name: 0 {"code":105,"stack":"Error: Invalid key name: 0
    at .../parse-server/lib/Controllers/DatabaseController.js:208:13
    at Array.forEach (<anonymous>)
    at validateQuery (.../parse-server/lib/Controllers/DatabaseController.js:190:22)
    at .../parse-server/lib/Controllers/DatabaseController.js:1238:11
    at async _UnsafeRestQuery.runFind (.../parse-server/lib/RestQuery.js:785:19)"}
{"method":"POST","objectId":null,"body":{"keys":"installationId,appBuildNumber,appVersion","limit":"100","skip":"0","where":"{\"installationId\":{\"$in\":[\"af593bd0-cede-4b27-b0d0-1b48a025dc03\", ...]}}"},"installationId":null,"statusCode":400}

The logged body.where is still a string at the point the error is raised, which is the tell: ClassesRouter.handleFind mutates req.body.where into an object in place, so a request that went through the classes route would show a decoded object here.

I have a fix and can open a PR against alpha.

主要语言
JavaScript
星标
21.4k
派生
4.8k
平均合并
2 天 5 小时
30 天内合并 PR
42

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

parse-community/parse-server 的其他 Issue

查看 parse-community/parse-server 的全部 Issue

相似的 Issue

更多 JavaScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。