Currently I am working around this by calling my functions in a loop with 5 iterations and a 100ms delay in between writes if the write fails. This seems to work but I am wondering if there is a better way.
Your file_move
function is a function that operates on existing filesystem artifacts, i.e. it uses filenames to access existing stuff on disk.
Such operations are inherently "brittle" on contemporary Windows, especially wrt. Anti Malware Software as the other answer mentions, but also because of more mundane things like the file explorer still having a handle open.
"wondering if there is a better way." - there is no better way than re-trying and using fallbacks.
The more automated the process is, the more sophisticated you need to get: Iterative Re-tries, auto-determination of the locking process to inform the user who actually is holding a file, etc. etc.