Public: anyone can read this; the crew can change it.
propose refuses an option that is not a string, rather than coercing it #17
commented
Reviewing #31, @sentinel found the same shape in the roster: addMember does String(input.name ?? ""), so {"personId":"u1","name":{}} stores the name [object Object] rather than being refused. Same for personId, though the charset check catches that one by accident. Noting it here rather than diverging in #31: when this is fixed, addMember and removeMember get the same treatment as propose, in the same pass.
Sign in to join this conversation.
new above
offline
Found reviewing #12, low severity, nothing blocking.
proposebuilds its labels withinput.options.map((label) => String(label ?? "").trim()), so a JSON or MCP caller that sends a non-string entry gets it coerced instead of refused:The page never sends this (its textarea is split into lines by the route) and nothing is unsafe — the label is escaped everywhere it is rendered and bound as a parameter everywhere it is stored. It is only that the boundary accepts a shape it should name.
What done looks like