But clearly, this is not the case as my programs do come up with (an approximate) solution though.
I believe you did not continue the integration until you see that your integration is not convergent and is not bounded.
I could rewrite your system of ODEs as:
$$\dot{x_{1}} = x_{2}$$
$$\dot{x_{2}} = -kx_{1}$$
Or in matrix form:
$$\dot{X} = AX$$
Where: $X = \begin{bmatrix}
x_{1} \\
x_{2}
\end{bmatrix}$ and $A = \begin{bmatrix}
0 & 1 \\
-k & 0
\end{bmatrix}$
The equilibrium point of your system of ODEs is: $X^{*} = \begin{bmatrix}
0 \\
0
\end{bmatrix}$, but this equilibrium point is unstable cause the real part of eigenvalues of $A$ are not all negative: $\lambda_{1} = i\sqrt{k}$ and $\lambda_{2} = -i\sqrt{k}$. In fact, the real part of eigenvalues are zero for these two eigenvalues. So, the conclusion is: no matter how you choose a small $\Delta t$, the forward Euler integration will not remain bounded.
Let's look at your discretization. I could discretize this system of ODEs in matrix form as:
$$X_{n+1} = (I+\Delta t A) X_{n}$$
Where $X_{n+1}$ and $X_{n}$ are $X$ vectors at times $n+1$ and $n$ respectively. The general formula is:
$$X_{n} = (I+\Delta t A)^{n} X_{0}$$
Where $X_{0}$ is initial condition for vector $X$. In order to have a bounded solution, I need to make sure the Frobenius norm of $||I+\Delta t A||_{F} < 1$. But we have:
$$||I+\Delta t A||_{F} = \sqrt{2+(1+k^{2})\Delta t^{2}} > 1$$
Which shows that no matter what you choose for $\Delta t$, if you continue the integration long enough, finally $(I+\Delta t A)^{n}$ will be blown up at some point.
This is the implementation with Python:
import numpy as np
import matplotlib.pyplot as plt
k = 1
deltats = np.linspace(0.01,0.1,5)
A = [[0,1],[-k,0]]
I = [[1,0],[0,1]]
A = np.array(A)
I = np.array(I)
X0 = [0,np.sqrt(k)]
X0 = np.array(X0)
for deltat in deltats:
x1 = []
x2 = []
B = I + deltat * A
ts = np.linspace(0,100,int(100/deltat))
for i,t in enumerate(ts):
C = np.linalg.matrix_power(B,i)
x1.append(np.matmul(C,X0)[0])
x2.append(np.matmul(C,X0)[1])
plt.plot(ts,x1,label=r'$x_{1}$, $\Delta t$ = '+str(deltat))
#plt.plot(ts,x2,label=r'$x_{2}$, $\Delta t$ = '+str(deltat))
plt.xlabel('t')
plt.ylabel('X')
plt.legend(loc='best')
plt.show()
And you see, when we expect the solution of this system of ODEs with initial condition of $X_{0} = \begin{bmatrix}
0 \\
\sqrt{k}
\end{bmatrix}$ to be $X(t) = \begin{bmatrix}
\sin(\sqrt{k}t) \\
\sqrt{k}\cos(\sqrt{k}t)
\end{bmatrix}$ and clearly the solution should be bounded smaller than 1, but you see it's not bounded when you continue the integration long enough: