S.Trim.pipe(S.compose(S.NonEmptyString))? Because S.NonEmptyTrimmedString doesn't seem to be it. S.NonEmptyTrimmedString uses S.Trimmed (which uses the trimmed filter), which filters the input, validating if the input string is already trimmed or not, and failing if it is not, but not actually trimming it before validating that it's not empty.