A StackOverflow answer has a possible explanation:
Each time the SQL Agent starts, it puts a new row in syssessions and
subsequently any jobs run will get that session_id in sysjobactivity.
For your jobs that have a null stop date, my guess is that they're not
for the "current" session which would mean that they were still
running when the agent was stopped.
I had a similar issue where two entries in sysjobactivity appeared to be "stuck", with a start_execution_date from six weeks back and no stop_execution_date. Following the suggestion in the quote above I checked the session_id for each of those stuck records and found in each case the stuck records were from previous sessions.
The following StackOverflow answer shows how to get only the activity for the current session:
DATEDIFF( SECOND, activity.run_requested_date, GETDATE() ) as Elapsed
job.job_id = activity.job_id
sess.session_id = activity.session_id
MAX( agent_start_date ) AS max_agent_start_date
sess.agent_start_date = sess_max.max_agent_start_date
run_requested_date IS NOT NULL AND stop_execution_date IS NULL