It turns out that the command I was calling, sqlcmd.exe, was using the SQL Server 2008 (c:\Program Files\Microsoft SQL Server\100\Tools\Binn) version on my colleague's machine and build machine, but the SQL Server 2012 (c:\Program Files\Microsoft SQL Server\110\Tools\Binn) version on my machine. Changing the path variable to point to the SQL Server 2008 version on my machine worked.
Maybe it will be of interest that the "Timeout expired" message is written to stdout instead of stderr in SQL Server 2012's sqlcmd.exe when the .sql script your running takes longer than the sqlcmd.exe -t, query timeout, parameter is set to.