What you see is the intended behavior when you use the basic completion mechanism `complete -W`.
If you want a more intelligent completion, you need to to write completion functions (see the "Programmable Completion" section in the Bash manual) and use `complete -F`.
Here is how to adapt your example:
$ comp_d() {
COMPREPLY=( $(
if [ "$COMP_CWORD" -eq 1 ]; then
compgen -W "exempt limit show update" "$2"
fi
) )
}
$ complete -F comp_d d
Such functions must return the completion candidates in an array `COMPREPLY`. I only use your word list when the user is completing the first argument (`COMP_CWORD` is 1), else the array is left empty.