Match ends, Walsall 0, Bristol City 1.
A first-half penalty by Sam Baldock moved Bristol City up to 13th in League One while all but ending Walsall's slim hopes of making the play-offs.
Baldock hammered home his 23rd goal of the season after Andy Taylor fouled him needlessly in a corner of the box a minute from half-time.
The Saddlers should have equalised in the 57th minute when Greg Cunningham fouled Michael Ngoo in the area.
However, Sam Mantom's soft spot-kick was comfortably saved by Simon Moore.
Walsall boss Dean Smith told BBC WM:
"Unfortunately they've scored theirs and we've not scored ours - two weeks on the spin we feel aggrieved.
"When the penalty was missed - or saved - I think the players felt it mentally because they've been playing well.
"We've certainly promised an awful lot this season and we've made great strides again in terms of how we play.
"It's our duty to go and compete. We owe it to other teams and ourselves to make sure the season doesn't peter out."
Bristol City manager Steve Cotterill told BBC Radio Bristol:
"We haven't been as expansive as we have been and not quite as good as we have been - football-wise - in the first half.
"Sometimes you need to do that away from home and we've needed to do that today. I said earlier in the season I thought Walsall are a good team and I think they are.
"I think they are one of the best teams we've played and we knew coming here was going to be a tough game.
"We've had three tough games. Today we've got a tough three points, where a point would have probably been about right."
- 7ChambersSubstituted forFeatherstoneat 86'minutes
- 30NgooBooked at 38minsSubstituted forBakayokoat 67'minutes
- 16BaxendaleSubstituted forMcQuilkinat 73'minutes
- 11WagstaffSubstituted forPearsonat 89'minutes
- 17CunninghamBooked at 57mins
- 35OsborneBooked at 65mins
- 10Emmanuel-ThomasSubstituted forBarnettat 78'minutes
- 24PatersonSubstituted forMoloneyat 67'minutes
- Nigel Miller
- Shots on Target
Second Half ends, Walsall 0, Bristol City 1.
Attempt blocked. Febian Brandy (Walsall) right footed shot from the left side of the box is blocked.
Attempt blocked. Amadou Bakayoko (Walsall) right footed shot from the left side of the box is blocked.
Substitution, Bristol City. Stephen Pearson replaces Scott Wagstaff.
James McQuilkin (Walsall) wins a free kick in the defensive half.
Foul by Greg Cunningham (Bristol City).
Corner, Walsall. Conceded by Simon Moore.
Attempt saved. Nicky Featherstone (Walsall) right footed shot from outside the box is saved in the top right corner.
Substitution, Walsall. Nicky Featherstone replaces Adam Chambers because of an injury.
Attempt saved. Tyrone Barnett (Bristol City) right footed shot from outside the box is saved in the bottom right corner.
Attempt saved. James McQuilkin (Walsall) right footed shot from outside the box is saved in the bottom right corner.
Foul by James Chambers (Walsall).
Greg Cunningham (Bristol City) wins a free kick in the attacking half.
Substitution, Bristol City. Tyrone Barnett replaces Jay Emmanuel-Thomas.
Attempt missed. James McQuilkin (Walsall) left footed shot from outside the box is close, but misses to the right.
Attempt blocked. Sam Mantom (Walsall) right footed shot from the right side of the box is blocked.
Corner, Bristol City. Conceded by James Chambers.
Attempt blocked. James Chambers (Walsall) right footed shot from outside the box is blocked.
Substitution, Walsall. James McQuilkin replaces James Baxendale.