Everything works as it should if this were about a pure functional programming language. Yes, it is lexical scoping.
$(\lambda x.(x\lambda x.x))a = a\lambda x.x$.
Basically, $\lambda x.x = \lambda y.y$. You are defining operations as you would expect in a programming language. So you do have to be careful about cases like $\lambda x.(x\lambda x.x)$.
So $\lambda a . (\lambda x.(ax))$ is an operation which, given applied to $b$, returns $\lambda x.(bx)$.
The worst case is something like this:
$$(\lambda a.\lambda x.(ax))x$$
A naive approach would yield $\lambda x.(xx)$. The rigorous definition to deal with this is a bit nightmarish. The Wikipedia page for $\lambda$-calculus has this fairly opaque language:
The freshness condition (requiring that y is not in the free variables of r) is crucial in order to ensure that substitution does not change the meaning of functions. ...
In general, failure to meet the freshness condition can be remedied by alpha-renaming with a suitable fresh variable.
Basically, we have to be careful when apply $\lambda x.E$ to an expression with a free $x$ variable in it.