Path too long exception while syncing

Hello,

We are using grunt to build a specific step in our building process. Let’s say the grunt directory structure is a little bit (too) verbose, but it will reach more than the allowed 255 characters in .NET. The strange thing is that we copy the source for node to the source directory on the agent. I wouldn’t expect Continua CI to fail during the workspace syncing process because the directory is excluded during the sync back to the server.

Probably you use the .NET API to access the files on disk. Make sure to only check the paths that you really need to check. In other words: don’t say “IncludeSubDirectories” on the top-level, but check it one-by-one. This might look a bit more work, but will allow you to prevent unexpected errors like this.

As a workaround we will delete the file as the last step in our build, but I think it should be fixed in Continua CI as well.

One small note: we also found a strange thing in FinalBuilder. It first checks whether the (too long) directory exists. That is true. But then we call the “Delete Directory” action and it fails that the directory does not exist.

I know supporting long paths in .NET is a painful process (been there myself), but there are some additional API’s out there that support it. You might want to consider it to get rid of this forever.

Thanks.

Hi Geert,

We do iterate through each directory and file when synching the workspace, only copying the files which match the Workspace Rules. If we can’t copy one file due to a long path then we log the error and fail the build. If you add an exclude rule e.g. -< /LongPathRoot/ then this path is ignored according to our testing. Can you post you workspace rules and we’ll look into why this is not working for you?

It’s on our to-do list to replace our System.IO calls at some stage and use a library such as Delimon.Win32.I​O library which works with long path names.

Here are the workspace rules:

/ < /Output**
Artifacts < Artifacts**
Logs < Logs**
Output\Test < Source\MyBranch\output\release\Test\MySoftware.Test.*


The issue files live in:

Source\MyBranch\src\MySoftware</i>

which should be ignored.

Deleting the folder manually works for now (which is the same workaround to me as ignoring while copying), so no haste to fix it. But I think it is good to fix this on the long term (especially users running grunt for example, their folder structure is idiotic…).

Hi Geert,

It’s strange that the folder doesn’t get ignored. Can you run a build with the delete folder action disabled and workspace rule logging turned on and then post the build log showing where the exception occurs?

Even though we have logging turned on, we get only this output:

[code] 10:00:29 Agent To Server Workspace Sync10:00:29 Started syncing files from the agent to the server.10:00:29 Workspace Syncing10:00:29 Using UNC Transport.10:00:29 / < /Output**10:00:29 10:00:29 10:00:29 An error occurred while syncing files from the server to the agent. Details: Exception: PathTooLongException 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. Stack Trace: at System.IO.PathHelper.GetFullPathName() at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths) at System.IO.FileSystemEnumerableIterator1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler1 resultHandler, Boolean checkHost) at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption, Boolean checkHost) at System.IO.Directory.InternalGetFileSystemEntries(String path, String searchPattern, SearchOption searchOption) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.<>c__DisplayClassa.<GetEmptyDirectories>b__8(String dir) at Continua.Shared.Utils.FileMatcher.GetEmptyDirectories(String basePath, IEnumerable1 patterns) at Continua.Modules.Builds.Agent.FileSync.UNCTransport.Copy(String destination, String pattern, IEnumerable1 excludes, String basePath, RuleOperator op, Int32& filesCounted) at Continua.Modules.Builds.Agent.FileSync.UNCTransport.ExecuteAgentToServerRule(String source, IEnumerable1 excludeRules, WorkspaceRuleDTO rule) at Continua.Modules.Builds.Agent.FileSync.UNCTransport.CopyFilesFromAgentToServer(String source, IEnumerable1 rules) at Continua.Modules.Builds.Agent.AgentBuildHelper.SyncWorkspaceToServer(TransportContextDTO context, IEnumerable1 rules, AgentWorkspaceSyncContext workspaceCtx) at Continua.Modules.Builds.Agent.AgentBuildRunner.OnSyncingWorkspace(Transition1 inState) .[/code]

Hi Geert,

I’ve reproduced this now. You can download a build with a fix using the following links:

Continua Server x64 v1.0.0.3094

Continua Agent x64 v1.0.0.3094

Thanks for the fast fix! Will test it out as soon as I can and let you know.

Fix confirmed! Thank you very much, good work.