args=${*:3}
flattens your argument list. You don't want to do that. Consider following the pattern given below instead:
# this next line sets "$@" for testing purposes; you don't need it in real life
set -- \
"first argument" \
"second argument" \
"third argument" \
"fourth argument" \
"fifth argument"
# trim the first two
args=( "${@:2}" )
# trim the last one
args=( "${args[@]:1:$(( ${#args[@]} - 2 ))}" )
# demonstrate the output content
printf '<%s>\n' "${args[@]}"
Running the above yields the following output:
<third argument>
<fourth argument>
...and, by doing so, demonstrates that it's correctly keeping arguments together, even when they contain spaces or wildcard characters.
For a shell completion script, you might also consider:
printf '%q ' "${args[@]}"
...which quotes content in such a way as to be eval'able by the shell.