I had a customer who mailed me about their builds failing. The error message wasException Message: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
The problem was the path of the source files got too long. There are 2 contributing factors for path length on a build server:
- The Build Agent Working Directory setting
- The Source Setting Workspace mapping
When the build agent checks out code, it checks it out to (WorkingDirectory)\Mapping for each mapping. By default, the build agent working directory is set to $(SystemDrive)\Builds\$(BuildAgentId)\$(BuildDefinitionPath) – more on these macros later – but this usually defaults the working directory that the source gets checked out to something likec:\Builds\1\FabrikamFiber\FabrikamFiber.CallCenter MAIN\src
(where the team project name is “FabrikamFiber” and the build definition name is “FabrikamFiber.CallCenter MAIN”).
Then, if you look at the Source Setting workspace mapping for the build, you’ll see the mappings for what source code the build is supposed to check out:
Here, $(SourceDir) equates to the root working folder for the build agent that ends up running the build. You’ll see I have a 2 mapping here – one to $(SourceDir) and one to $(SourceDir)\BuildLibs. That means that my BuildLibs will get checked out to:c:\Builds\1\FabrikamFiber\FabrikamFiber.CallCenter MAIN\src\BuildLibs
which is already 69 characters. If I have lots of subdirectories below that, I could start hitting the 260 character path limit.
Customizing the Build Agent Working Directory
So let’s shorten the build agent working directory. In Team Explorer, click on the Build hub. Click “Actions” and select “Manage Build Controllers”.
Then find the build agent(s) that are going to build your code and click “Properties”. You want to set the working directory to something shorter:
There are 4 macros you can use here (according to this page):
$(BuildAgentId): An automatically generated integer that uniquely identifies a build agent within a team project collection.
$(BuildAgentName): The Display Name of the build agent.
$(BuildDefinitionId): An automatically generated integer that uniquely identifies a build definition within a team project collection.
- $(BuildDefinitionPath): The team project name and the build definition name, separated by a backslash.
So let’s change the Working Directory to:c:\b\$(BuildAgentId)\$(BuildDefinitionId)
That means the root of the working directory will be something like:c:\b\1\10\src
which is only 13 characters.
Shorten the Build Source Setting Workspace Mapping
Nothing says that the mapped folder for the build has to have the same name as the folder in source control. For example, if you have$/FabrikamFiber/Code In Some Really/Long Folder/That has SubFolders/Within SubFolders
and you need to map a path to$/FabrikamFiber/Code In Some Really/Long Folder/Libs
for referencing a library, then you could map those 2 folders to$(SourceDir)/T/W
respectively. As long as you keep the same relative path “distances”, any relative path references you have will just work (assuming you haven’t hard coded them).