Great work!

XP to next level

BugEater

When Whitespace Breaks Logic

Understanding where whitespace bugs originate is half the problem. The other half is understanding what breaks downstream — because whitespace issues rarely manifest where they were introduced.

Authentication Failure (No Error Message)

The most common whitespace production bug: a user cannot log in, but there is no error message saying why. The login endpoint validates the submitted credentials against stored values. The match fails. The UI says "Invalid credentials."

From the server's perspective, this is correct behavior — the credentials don't match. But the user is certain they are entering the right password/username. Both are correct: the stored value has leading or trailing whitespace that was accepted during registration, and the login form does not have the same whitespace.

This bug is intermittent and user-specific. It affects only users whose registration involved copy-paste from a source that added invisible or standard whitespace. Because it is hard to reproduce, support tickets are often resolved by "resetting" the account — which also clears the whitespace-corrupted value.

Search Misses

A search for admin that returns zero results when the database contains admin (with leading space) is a whitespace search bug. Depending on the database and its collation settings:

  • PostgreSQL: WHERE username = 'admin' does NOT match admin — exact match
  • MySQL with utf8mb4_general_ci: may or may not trim for comparison depending on version
  • Application-layer search: usually exact match unless trimming is explicit

A user searching for their own account by name finds nothing, even though they can see it when scrolling through all results. Support cannot reproduce it because they search with a clean value.

Database Uniqueness Violations

Most usernames have a UNIQUE constraint. But what constitutes "unique" depends on whether whitespace is normalized before the unique check:

  • admin and admin are different strings — the unique constraint allows both
  • If the system accepts admin, two "admin" accounts now exist
  • Any feature that looks up "the admin account" by exact match will find different accounts depending on which whitespace variant it was given
  • Reset password, permission check, profile lookup — each might find a different record

The inverse also happens: the system rejects admin as "already taken" even though the existing account is actually admin. The unique check matches because the system trims before checking but stores the raw value.

Multi-Service Inconsistency

In microservice architectures, whitespace bugs become multi-service inconsistency bugs:

  1. Service A (registration) accepts admin and stores it as admin (trims before storing)
  2. Service B (profile service) receives admin in a JWT claim and stores it as admin (does not trim)
  3. Service C (search) queries with admin and finds Service A's record but not Service B's

The same user now has different representations in different services. Some features work, some don't. The inconsistency is invisible and grows over time as more records accumulate the mismatch.

The Specification Question

The right way to avoid these bugs starts at specification time. For every text field:

  1. Should leading/trailing whitespace be accepted or rejected? Rejected means the frontend validates immediately and shows an error. Accepted means the backend normalizes.

  2. Should the stored value include or exclude surrounding whitespace? "Include" means comparisons must always normalize. "Exclude" means storage normalizes once.

  3. Are internal spaces valid? For most usernames: no. For names and free-text fields: yes.

  4. What whitespace characters are in scope? Just ASCII whitespace (U+0009, U+000A, U+000D, U+0020)? Or also U+00A0, U+200B, and others?

As a tester, if you cannot find clear answers to these questions in the requirements, that is a gap. Raise it before writing tests — the answers determine what behaviors are bugs and what are features.

Quiz

A coupon code SAVE20 is stored in the database. A user enters SAVE20 (trailing space). The system performs direct string equality. What is the result?

A search endpoint returns zero results for "Berlin" even though the database contains that city. No errors logged. What should the tester check first?

An API stores " Paris " (with spaces) as a grouping key. After weeks the dashboard shows both "Paris" and " Paris " as separate cities. What caused this?

A tester wants to verify that whitespace does NOT break an exact-match filter. Which boundary values are most important?