Commit bbeb378
committed
fix(actions): skip non-string entries in formatActionSimiles/Tags
Production observation (2026-04-28): the bot dropped a user message
in cozy ("@remilio nubilio would you like that? look what me and shaw
were just talking about ...") and stayed silent. Bot log showed:
[PLUGIN:DISCORD] Error handling message
(error=undefined is not an object (evaluating 'tag.trim'))
Trace: plugin-discord's messageCreate handler called the runtime's
formatActions to build the planner prompt. One of the registered
actions had `tags` containing a non-string entry (undefined or null —
the array was malformed somewhere upstream). The chain
`(action.tags ?? []).map((tag) => tag.trim())` then called .trim()
on undefined and threw. plugin-discord caught the throw as the
generic "Error handling message" and aborted the entire message
pipeline before reaching the planner. No reply, no specific log line
about which action / which tag — just silence.
Same shape exists in formatActionSimiles for action.similes.
Fix: filter out non-string entries before .trim() in both helpers.
String entries still trim/dedupe/empty-filter the same way.
```diff
function formatActionTags(action: Action): string | null {
const tags = [
- ...new Set((action.tags ?? []).map((tag) => tag.trim())),
+ ...new Set(
+ (action.tags ?? [])
+ .filter((tag): tag is string => typeof tag === "string")
+ .map((tag) => tag.trim()),
+ ),
].filter((tag) => tag.length > 0 && tag !== "always-include");
```
Why filter rather than rely on the Action type contract: action.tags
and action.similes are `string[]` per the Action type, but external
plugin authors are not always strict — a malformed entry from an
inadequately-typed source poisoning the array crashes the entire
planner-prompt builder, which silently kills message handling for
every message the bot receives until the offending plugin is fixed.
The cost of a `typeof === "string"` filter is negligible; the failure
mode it prevents (silent bot, no actionable diagnostic) is severe.
Tests: two regression cases in actions.test.ts covering action.tags
and action.similes with mixed [undefined, null, string, number]
arrays. Both should produce a normal formatted output with only the
real string entries surviving.1 parent 2f998a4 commit bbeb378
2 files changed
Lines changed: 74 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
301 | 365 | | |
302 | 366 | | |
303 | 367 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
212 | 212 | | |
213 | 213 | | |
214 | 214 | | |
215 | | - | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
216 | 220 | | |
217 | 221 | | |
218 | 222 | | |
| |||
224 | 228 | | |
225 | 229 | | |
226 | 230 | | |
227 | | - | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
228 | 236 | | |
229 | 237 | | |
230 | 238 | | |
| |||
0 commit comments