Backend Log

I robbed my own bank by forgetting one return

8 September 2026GoErrorsBackend

Today, writing errors/bank_withdrawal.go, I robbed my own bank.

What I wanted to understand

I knew Go returns errors instead of throwing them. What I had not understood is that creating an error does nothing on its own.

What I wrote

go
func withDrawMoney(balance int, amount int) (int, error) {
	if amount <= 0 {
		errors.New("invalid withdrawal amount") // created, never returned
	}
	remainingBalance := balance - amount
	return remainingBalance, nil
}

What happened

code
Transaction successful... -1000

A withdrawal larger than the balance went through, and the account went negative.

Why

errors.New(...) builds an error value and hands it back. On its own line it is simply discarded. Execution carried on to return remainingBalance, nil, so main saw a nil error and reported success.

The fix

go
if amount <= 0 {
	return 0, errors.New("invalid withdrawal amount")
}

The return is the whole point. And because the function returns (int, error), the int slot gets a zero value when the error is real.

Where this matters

Anywhere validation can fail — payments, inventory, auth. An error that is built but not returned is a silent success, which is worse than a crash: the caller never learns anything went wrong.