Your assumption is generally right, but only when you use only clean Nim code. Not when you use C libs, casts, addr() and pointers. With the later you can do very dirty things, you can un-intentionally overwrite references for example. And then, when the the GC tries to free memory pointed to by that references the wrong memory address is used. Different GC's may react different to such errors. Your observation that the error does only occur with -d:release may indicate only that the error is somehow hidden without -d:release. Debugging code which is included in the executable without -d:release moves memory addresses, so the buggy code may still overwrite data in illegal ways, but when it only overwrites unimportant data, then you may see no crash.
You should try to get your program compile with ARC. Good Nim software compiles fine with ARC. And then you can use the compiler option --gc:arc -d:useMalloc and run your executable with valgrind, which may give you a detailed error report.