Skip to content

Validate BotMaker collection helpers on empty/out-of-range input - #218

Open
jainprayush9 wants to merge 1 commit into
xai-org:mainfrom
jainprayush9:fix/botmaker-empty-collection-guards
Open

jainprayush9 wants to merge 1 commit into
xai-org:mainfrom
jainprayush9:fix/botmaker-empty-collection-guards

Conversation

@jainprayush9

@jainprayush9 jainprayush9 commented Sep 26, 2026 •

Copy link
Copy Markdown

Problem

BotMaker collection helpers in botmaker/.../function/collection/ assumed valid inputs and called into the JDK without bounds checks:

Helper Failure mode
First() list.get(0) on empty → IndexOutOfBoundsException
Last() list.get(size - 1) on empty → get(-1) → IndexOutOfBoundsException
FirstN() negative n → subList(0, negative) → crash
Slice() / Substring() out-of-range begin/end → StringIndexOutOfBoundsException / IndexOutOfBoundsException
ElementAtIndex() null list or bad index → NPE / IndexOutOfBoundsException

FunctionNode*.toExtractor() wraps those exceptions in FunctionFailure, so the worker does not die — but the enclosing BotMaker rule does not complete. In the scarecrow flow that means the intended label is never applied. Whether the caller fails open or closed is outside this repo; either way, silent rule abortion is the wrong outcome for empty or malformed collections.

This was reported for First / FirstN / Slice in #58 and extended to Last() in #207 (same defect class, one function later in the file).

Solution

Validate at the function boundary and raise a typed FunctionFailure with a clear IllegalArgumentException message (same pattern used elsewhere in BotMaker, e.g. Any batch-size checks):

  • First / Last — reject null or empty lists before index access
  • FirstN — reject null list; clamp n with Math.max(0, n) before subList
  • Slice — validate non-null indices and 0 ≤ begin ≤ end ≤ length for both String and List inputs
  • ElementAtIndex — reject null list / null index and out-of-range indices (same class of bug; included so the collection API is consistent)

Happy paths are unchanged. Descriptors / signatures / examples are unchanged.

Files

  • botmaker/src/java/com/twitter/botmaker/function/collection/First.java
  • botmaker/src/java/com/twitter/botmaker/function/collection/Last.java
  • botmaker/src/java/com/twitter/botmaker/function/collection/FirstN.java
  • botmaker/src/java/com/twitter/botmaker/function/collection/Slice.java
  • botmaker/src/java/com/twitter/botmaker/function/collection/ElementAtIndex.java

Test plan

  • Empty First(List()) / Last(List()) → FunctionFailure with message mentioning empty list
  • FirstN(list, -1) → empty prefix (clamped), not a crash
  • Slice / Substring with begin < 0, end < begin, or end > length → FunctionFailure with bounds in the message
  • ElementAtIndex(list, -1) and ElementAtIndex(list, size) → FunctionFailure
  • Non-empty happy paths still work: First(List(1)), Last(List(1, 2)), FirstN(List("a","b","c"), 2), Slice([1,2,3,4], 1, 2), ElementAtIndex(List("hello", 42), 0)
  • Existing BotMaker / scarecrow CI (if present) stays green

References

Empty or out-of-range inputs to First/Last/FirstN/Slice/ElementAtIndex
threw raw IndexOutOfBoundsException, which aborted scarecrow labeling
rules. Surface typed FunctionFailure with clear messages instead.

Fixes xai-org#207
Related to xai-org#58

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BotMaker collection plus same defect class in Last()

1 participant