For what I saw, if you're playing the file with BASS_StreamCreateFile then the 3DLite's Tags Library
https://www.3delite.hu/Object%20Pascal%20Developer%20Resources/TagsLibrary.html will write the metadata if the necessary space in the file is already allocated. This is the case with ID3v1 tags, but with variable-lenght tags the space may not be enough and a complete re-write of the file may be necessary. In this case you must free the stream.
It may be possible to load the entire file into memory and play it from there, for instance using the BASS_ASYNCFILE flag and providing a big enough buffer. The file buffer is determined by the BASS_CONFIG_ASYNCFILE_BUFFER config option.
Another option is to copy the file and write the tags to the copy. Then after you're done playing the original, delete it and rename the copy.
Yet another option is the one you mention: delay the writing of the tags until the stream is freed. This seems to be the easiest.
I've tried all 4 options and none is fool-proof.
All 4 options may fail if the same file is locked by another process, for instance if it's being played by VLC or WMP (even if it's paused) and BASS_StreamCreateFile simultaneously.
With certain file types it's possible to play the file while it's being written (recorded). Some of them support mid-stream tags, and you can write them on the fly along with the audio. For instance, wma.