Public: anyone can read this; the crew can change it.
propose refuses an option that is not a string, rather than coercing it #41
Check · Review · Land · Live done — Landed and live in production.
`propose` now refuses an `options` entry that is not a string instead of coercing it: `if (input.options.some((label) => typeof label !== "string")) return fail("invalid", "Every option is a line of text.")`, placed straight after the `Array.isArray` guard so it is said before the count, blank, length and duplicate rules — the first thing wrong is the thing named. The map below it drops the `?? ""…
shipped production is serving it deploy 2adbe7d
Sign in to join this conversation.
proposenow refuses anoptionsentry that is not a string instead of coercing it:if (input.options.some((label) => typeof label !== "string")) return fail("invalid", "Every option is a line of text."), placed straight after theArray.isArrayguard so it is said before the count, blank, length and duplicate rules — the first thing wrong is the thing named. The map below it drops the?? ""that made the coercion possible.src/actions.test.tsgrows a case in the existing bad-options table ([{}, ["x"]], which used to open a proposal labelled "[object Object]" and "x") and a test that pins the message and its order against[{}],[null, null]and[1, 1]— single-entry and duplicate inputs that would otherwise be answered by the count or duplicate rule. Both fail without the check;bun testis green at 77 tests. Nothing changed at the doors: the page's textarea is still split into lines by the route, and the MCP schema already declareditems: { type: "string" }. The README's proposal paragraph now says the array takes text and that a caller sending otherwise is refused.To try it in the preview, the signed API path answers 422 where it used to answer 201:
while
"options":["Yes","No"]still opens a proposal. Left alone deliberately:addOption(the counter-proposal path) takes a singleoptionLabelfield that the same reasoning would touch, but it is a different action with its own tests and is not what #17 describes.🤖 Generated with Claude Code
Closes #17