Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

npm in vagrant-ubuntu on windows dies on "unknown error" when dirs are too long #3670

Closed
Pomax opened this issue Jul 18, 2013 · 10 comments
Closed

Comments

@Pomax
Copy link

Pomax commented Jul 18, 2013

I'm using vagrant at the moment to see if I can set up a convenient test environment, currently testing on windows, but I'm running into an npm problem where some modules have incredibly deep chains, going past the windows NTFS path limit of 256~260 characters. However, unlike in plain windows, the error in vagrant is proxied and ends up being "unknown":

npm ERR! Error: UNKNOWN, mkdir '/vagrant/login.webmaker.org/node_modules/i18n-abide/node_modules/jsxgettext/node_modules/jade/node_modules/monocle/node_modules/readdirp/examples/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/example'

Running the mkdir outside of npm in the same dir leads to:

mkdir: cannot create directory `/vagrant/login.webmaker.org/node_modules/i18n-abide/node_modules/jsxgettext/node_modules/jade/node_modules/monocle/node_modules/readdirp/examples/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/example': Protocol error

Vagrant doesn't report the error as a dir-length issue, simply calling it a protocol error, but this chain is too deep for windows to manage. I don't know if there's a flag to tell npm to just put all modules necessary in the base dir so that there's no duplication/deep chaining, but I've been running into the path depth a lot more recently, and while on windows npm can deal with it, in vagrant it apparently can't (yet).

@isaacs
Copy link
Contributor

isaacs commented Jul 19, 2013

There will always be issues when a windows filesystem is used in a Unix system, because Node cannot possibly know that it's a Windows FS. So, symlinks fail, long dir names cause problems, etc. In the Windows OS, Node can use UNC paths for long dirs, and junctions for symlinks, etc.

The moral of the story: use the actual file system.

@isaacs isaacs closed this as completed Jul 19, 2013
@Pomax
Copy link
Author

Pomax commented Jul 19, 2013

wish that I could; vagrant's not really being that accommodating. The symlinks aren't much of a problem with the --no-bin-links flag, It seems to really just be the path length error. If there's no way to detect that when npm's used in vagrant, then too bad for me, but if there is, having npm work even in vagrant on windows would be a definite deploy win.

@isaacs
Copy link
Contributor

isaacs commented Jul 19, 2013

You could run your npm install on Windows, and then map that folder.

Or do your development in a non-shared path, and symlink in the shared place for you to just edit your code.

I'd like to help you, but really, limitations of Windows and Vagrant (virtualbox, really) are outside my sphere of influence. Sorry.

@Pomax
Copy link
Author

Pomax commented Jul 19, 2013

no worries. maybe I can convince the vagrant folks to generate the same error that windows does... thanks!

@davidmyersdev
Copy link

I've spent about 16 hours working on this today (I wish I was exaggerating), and I finally have a solution to the Vagrant/Windows issue at hand. I have been working on a Node.js development environment built on Vagrant, and I have been relentlessly determined to get this working.

This is the commit that I implemented it in, but I'll go ahead and post the main snippet of code here:

config.vm.provider "virtualbox" do |v|
    v.customize ["sharedfolder", "add", :id, "--name", "www", "--hostpath", (("//?/" + File.dirname(__FILE__) + "/www").gsub("/","\\"))]
end

config.vm.provision :shell, inline: "mkdir /home/vagrant/www"
config.vm.provision :shell, inline: "mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` www /home/vagrant/www", run: "always"

In the code above, I am appending \\?\ to the current directory absolute path. This will actually force the Windows API to allow an increase in the MAX_PATH variable (normally capped at 260). Read more about max path. This is happening during the sharedfolder creation which is intentionally handled by VBoxManage and not Vagrant's "synced_folder" method. The last bit is pretty self-explanatory; we create the new shared folder and then make sure it's mounted each time the machine is accessed or touched since Vagrant likes to reload its mounts/shared folders on each load.

I absolutely hope this helps everyone that was struggling with this like I was!

@othiym23
Copy link
Contributor

Thanks for writing this up, @drmyersii! I've gone ahead and copied your explanation into the Troubleshooting page on the wiki, so it should reach a broader audience.

@Pomax
Copy link
Author

Pomax commented Mar 18, 2015

nice! was this a PR into Vagrant itself, too?

@Pomax
Copy link
Author

Pomax commented Mar 18, 2015

ah, I see hashicorp/vagrant#5495 -- perfect!

@Jakobud
Copy link

Jakobud commented Jul 2, 2015

When I add the above to my CentOS Vagrantfile I get:

/sbin/mount.vboxsf: mounting failed with the error: Protocol error

Am I missing something here?

UPDATE: Fixed. I was getting this error because I hadn't created the www directory yet in the host machine. So for anyone else who comes across this solution, it will NOT automatically create the shared folder on the host machine like Vagrant's automatic shared folder options. So I would add the following to your Vagrantfile ABOVE the above code:

# Automatically create www directory on host if it doesn't exist
unless File.directory?(File.dirname(__FILE__) + "/www")
  FileUtils.mkdir_p(File.dirname(__FILE__) + "/www")
end

This will ensure that your host directory actually exists before the mount occurs on the guest which should prevent the protocol error.

Also don't forget to add run: "always" to the end of the mkdir provision shell command just in case you are attempting to do this on an already-provisioned environment.

@dantheman213
Copy link

Hey guys, I created a script to fix this issue. My solution was to execute the project in a part of the VM that wasn't being shared with Windows. The script can be run over and over again to run a project. It copies the base project to a temporary execution directory. If you're running it 2nd time + it checks for file differences and will run npm install if your "package.json" file has changed. Lastly it runs npm install inside the execution directory and voila! Workaround complete. :)

Check it out here guys:
https://gist.github.com/dantheman213/7a505004d26c480e8274

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants