everything/tasks: tasks/update checks MAX_ANSWER_BYTES against string length, so non-ASCII answers exceed the documented byte budget
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 1/5
- Tempo stimato
- Meno di un'ora
- Idoneità per principianti
- 78/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- backend
Direzione di ricerca
Il controllo delle dimensioni si trova nel gestore tasks/update in src/everything/server/tasks.ts, intorno alle righe 411-424, dove JSON.stringify(answered).length viene confrontato con MAX_ANSWER_BYTES. Leggi quel blocco, poi riproduci il problema inviando una risposta di 33.000 caratteri é e verificando che venga accettata. L'obiettivo è raggiunto quando la misura conta i byte UTF-8, così che quel payload riceva un errore -32602 e l'attività resti invariata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
| Field | Value |
|---|---|
| Labels (suggested) | bug, everything, tasks |
| Reproduced on | commit 163a5e935756 (default branch at the time of analysis) |
| Introduced by | commit 27b2d2415cdc0ad13782edb8b6c3cecd7846b78a — "feat(everything): serve both protocol eras and demonstrate …" |
Summary
The everything server's tasks/update handler limits the size of client-supplied answers with
MAX_ANSWER_BYTES, but computes the size with JSON.stringify(answered).length. In JavaScript that is
the number of UTF-16 code units, not bytes. For any non-ASCII answer the guard under-counts by up to
3× and lets a payload that is larger than the documented byte budget through, after which the oversized
answers are handed to task.behavior.receive() and retained in the task.
Affected code
src/everything/server/tasks.ts, lines 411–424 at 163a5e935756:
const answered = Object.fromEntries(
Object.entries(inputResponses).filter(([key]) =>
outstanding.includes(key),
),
);
const size = JSON.stringify(answered).length; // <- UTF-16 code units, not bytes
if (size > MAX_ANSWER_BYTES) {
throw new ProtocolError(
ProtocolErrorCode.InvalidParams,
`Invalid params for tasks/update: the answers are ${size} bytes, over the ${MAX_ANSWER_BYTES}-byte limit; the task is unchanged`,
);
}
if (Object.keys(answered).length > 0) {
task.behavior.receive(answered, now);
}
The constant is named MAX_ANSWER_BYTES and the error message promises a byte comparison
("the answers are N bytes"), so the unit mismatch is internal to the handler, not a documentation
question.
Expected behavior
tasks/update rejects the request with -32602 Invalid params because the serialized answers are
66 012 bytes, which is over the 65 536-byte budget; the task is left unchanged.
Actual behavior
Calling tasks/update with one outstanding answer whose text is 33 000 é characters, the handler accepts the payload and retains it in the task (MAX_ANSWER_BYTES = 65536).
Payload: one outstanding answer whose text is 33 000 U+00E9 (é) characters.
MAX_ANSWER_BYTES = 65536.
{"mode":"bug","outcome":{"accepted":true,"received":66012}}
TASKS_UPDATE_BYTE_BUDGET_BYPASSED
JSON.stringify(...).length= 33 012 → passes the guard.- UTF-8
Buffer.byteLength(..., "utf8")= 66 012 → 476 bytes over the limit. - The task retained the answer (
received: 66012), so the documented limit was not enforced.
Control: the same probe against a copy of tasks.ts with line 416 changed to
Buffer.byteLength(JSON.stringify(answered), "utf8") produces
{"mode":"control","outcome":{"accepted":false,
"error":"-32602: Invalid params for tasks/update: the answers are 66012 bytes, over the 65536-byte limit; the task is unchanged"}}
CONTROL_REJECTED_BY_BYTES
and retained is undefined — the divergence disappears with that one line.
Why it matters
- The limit is a resource guard for retained task state (the answer is stored until the task settles).
Non-ASCII answers — ordinary for any non-English client, or for base64/emoji content — get up to a 3×
larger effective budget. 33 000 characters of CJK/Cyrillic/emoji-style text becomes ~99 KB against a
stated 64 KiB ceiling. - The rejection message itself reports a byte count that is not a byte count, which makes the failure
mode confusing for client authors.
Suggested fix
Use a byte-accurate measure:
const size = Buffer.byteLength(JSON.stringify(answered), "utf8");
(new TextEncoder().encode(...).length if the file must stay runtime-agnostic). Note that both forms
count the UTF-8 serialization of the JSON text, which is what the limit documents.
- Lingua principale
- TypeScript
- Stelle
- 91.7k
- Fork
- 11.9k
- Merge medio
- 3h 30m
- PR unite (30g)
- 204
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di modelcontextprotocol/servers
-
fix(docker): correct stale --db-path comments in fetch/git Dockerfiles and clarify git READMEApertabug v2
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
modelcontextprotocol/servers#5483 ·
I maintainer di solito rispondono entro 1 giorno
-
bug v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
modelcontextprotocol/servers#5482 ·
I maintainer di solito rispondono entro 1 giorno
-
chore dependencies server-filesystem v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
modelcontextprotocol/servers#5481 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
CI: rename everything-mcp-diff.yml to mcp-interface-diff.yml, staged across a milestone mergeApertachore v2
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
modelcontextprotocol/servers#5463 ·
I maintainer di solito rispondono entro 1 giorno
-
bug server-filesystem v2
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
modelcontextprotocol/servers#5260 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di modelcontextprotocol/servers
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
shoelace-style/webawesome#2979 ·
I maintainer di solito rispondono entro 1 giorno
-
Chip source filter and denial markers miss Storage rows when a Storage activity source is pickedApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
omdsh-dev/DSH-better-sidebar#1141 ·
I maintainer di solito rispondono entro 2 giorni