I have a code that looks like this:

enum TextHelper {
  /// Searches for a first word that contains searchText inside / starts with it.
  static func findWord(with searchText: String, in sentence: String) -> String? {
    let searchTextNoWhitespace = searchText.trimmingCharacters(in: .whitespaces)
    guard
      let range = sentence.range(
        of: searchTextNoWhitespace,
        options: [.caseInsensitive, .diacriticInsensitive])
    else { return nil }

    // Not interested in words ending with searchText
    guard range.upperBound != sentence.endIndex else { return nil }
    guard !sentence[range.upperBound].isWhitespace else { return nil }

    return findWord(around: range.upperBound, in: sentence)
  }

  static func findWord(around index: String.Index, in text: String) -> String? {
    var start = index

    // We start from match index, and go left looking for whitespace
    while start > text.startIndex && !text[start].isWhitespace {
      start = text.index(before: start)
    }
    // Previous while loop stops when it sees whitespace, so start index will point before the symbol that we need.
    if start != text.startIndex {
      start = text.index(after: start)
    }

    var end = index
    // Start from last match index, and look till the next whitespace or end of the string.
    while end < text.endIndex && !text[end].isWhitespace {
      end = text.index(after: end)
    }

    return String(text[start..<end])
  }
}

And it crashes for some users on start = text.index(before: start) with Swift/StringCharacterView.swift:98: Fatal error: String index is out of bounds. I am expecting the body of the while loop not to be executed if start <= text.startIndex, so a call to index(before:) should be valid. Is it possible that range returned by range(of: options:) is "misaligned" (because of diacritics/etc), and when used as a param to index(before) it triggers this assert?

index(before:) | Apple Developer Documentation says:

Parameters

i

A valid index of the collection. i must be greater than startIndex.

Is it possible that your range starts at the very beginning of the string, and i = startIndex, and thus there is no characters before i (before startIndex)?