Use (...) instead of $(...), which will result in an array of strings even in the single-element case:
($CUBE_input.ToUpper() -split ';' -replace '(^\s+|\s+$)','' -replace '\s+',' ')[0]
$(...), the subexpression operator is rarely needed outside expandable strings (if you need to embed expression and commands in "..." strings).
Outside of expandable strings, you only need $(...) to embed whole statement(s) (such as if, do, switch, foreach, ...) in a larger expression or command, including providing a statement as the first segment of a pipeline.
In order to embed as single expression or a single command or pipeline in a larger expression or command, use (...), the grouping operator, which avoids the side effects of $(...) - see below.
As for what you tried:
$(...) applies pipeline output logic to the enclosed statements, which means:
Thus, by using $(...), the single-element array produced by -split (and preserved by the -replace operations) was effectively unwrapped, and the element itself - the string 'ABC' - was returned, and applying indices to strings extracts their individual characters; e.g. 'ABC'[0] returns 'A'.
Note that the above also implies that a 2+-element array that is strongly typed is transformed to a new [object[]] array by $(...); e.g.:
PS> $([string[]] ('a', 'b')).GetType().Name
Object[] # !! $(...) enumerated the array and
# !! collected the elements in a new [object[]] array
By contrast, (...) returns the expression's value as-is:
PS> ([string[]] ('a', 'b')).GetType().Name
String[] # OK: (...) preserved the array as-is