The simplest answer I can think of:
because we can make a finite look-up table for answers.
In other words, if you have a finite language $L = \{w_0, \ldots, w_{k-1}\}$,
consider the following algorithm:
Input: $x$
$L \leftarrow [w_0, \ldots, w_{k_1}]$
for $i$ from 0 to k-1 do
$~~$ if $x = L[i]$
$~~$$~~$ accept
reject
Now, the problem with your argument is that you are thinking of $M$ as input in one place and not thinking of it as input in another place. If $M$ is not part of the input then the machine does not decide the halting problem but only a fixed instance of it, so the algorithm for deciding it doesn't imply that the halting problem is decidable.
Note that we don't need to construct (uniformly in $M$) the algorithm deciding the halting of a given machine $M$, we only need to show that it exists, i.e. the process of finding the machine that decide if $M$ halts or not does not need to be a computable process (and it can't, if it could then your argument would go through).
On the other hand, if we assume that $M$ is a part of the input, then the set is not finite anymore. It is essentially $A = \{\langle M,b\rangle \mid \text{$b=0$ and $M$ halts}\}$. What you are doing is taking a slice of this set $B_M = \{ w \in A \mid \mathsf{fst}(w)=M \}$ which is finite and therefore decidable. But the decidability of all slices of a set does not imply the set itself is decidable. We need to be able to decide membership in $A$ uniformly in $M$, i.e. we need a single algorithm that works for all $M$, not a different algorithms for each $M$.