TL;DR: Here’s how you can “ignore” a .tool-versions
file in a Cloudflare Pages deployment: In the build settings, change the root directory to any folder of your project. Using a custom build command, either cd
back to the root directory or provide relative paths to the files required for the build. Note: The build process interprets the output directory path as a relative path from your root directory. If your “fake” root directory is /docs
and your site output directory is /site
, Cloudflare will expect the build output in /docs/site
.
The (very strange) issue
After recently migrating one of my projects to yarn, the Cloudflare Pages build for that project started failing. What confused me was Cloudflare installing Go and node.js from my asdf .tool-versions
file – for a MkDocs build, which only requires Python to be installed. The build then failed because Cloudflare tried to install node.js dependencies via yarn, triggering an asdf shim error.
Detected the following tools from environment: [email protected], [email protected], [email protected], [email protected]
Preparing [email protected] for immediate activation...
Installing project dependencies: yarn
No preset version installed for command yarn
Please install a version by running one of the following:
asdf install nodejs 20.16.0
or add one of the following versions in your config file at /opt/buildhome/repo/.tool-versions
nodejs 14.21.3
nodejs 16.20.2
nodejs 18.17.1
nodejs 20.19.0
nodejs 22.14.0
Error: Exit with error code: 126
There was absolutely no need to install Go, node.js, yarn or any related dependencies. I did have MkDocs selected as the “Framework preset” in the build settings, so I would have expected Cloudflare to know what is required to successfully run mkdocs build
.
Strange behaviour, sure. But let’s just tell Cloudflare to ignore the .tool-versions
file. Except you can’t. Cloudflare Pages neither offers a way to disable the automatic detection of tool versions nor any other way to ignore files in the repository. So rather than just adding .cloudflareignore
or .pagesignore
to the project, I went looking for a workaround. Despite a number of posts in the Cloudflare community forums (example) and answeroverflow (example), Cloudflare hasn’t responded to any of them. I also could not find an existing workaround, so I got to work.
The (somewhat strange) workaround
After some trial and error I noticed the very specific wording of this line in the build logs stating:
Found a .tool-versions file in user-specified root directory. Installing dependencies.
Root directory. User specified. What if I just specify some other directory as the root that does not contain the .tool-versions
file and then somehow switch back to the root directory for the build? In that directory, Cloudfare simply won’t see any version files? And, you guessed it: If it’s stupid and it works, it’s not stupid. It still took some trial and error to get the build to pass, but this approach actually works.
As noted above, this workaround requires you to use a custom build command. After all, you’re facing this issue because you usually run the build from the root directory of your project. You also need to provide a “Build output directory” that is a child directory of your root. Likely as part of their build “sandbox”, Cloudflare does not allow directory traversal in the build output path. If you don’t want to use a directory containing project files, I’d recommend just committing some dummy repository with a .gitkeep
file inside. Just remember to .gitignore
everything else in that directory to not risk accidentally committing build artifacts.
Finally, I had to manually install Python dependencies via pip. I suspect this step is only required because Cloudflare Pages thinks it’s build a node.js project and thus only installs dependencies via yarn. Because of this “misunderstanding”, I had to add explicitly define the node version (via a separate .node-version
) to get the node.js dependency install to pass.
It’s alive!
The build finally passed using the following settings:
Build command | pip install -r ../requirements.txt && mkdocs build -f ../mkdocs.yml && mv ../site . |
Build output directory | /site |
Build system version | 2 (latest) |
Root directory | /docs |
Environment variables | None |
I do hope Cloudflare addresses this issue at some point. For now, the workaround allows the build to pass without any changes to my project structure or pipeline. As a reference, here is the (almost) complete output of a build using the changes described above.
Cloning repository...
[...]
Using v2 root directory strategy
Success: Finished cloning repository files
Checking for configuration in a Wrangler configuration file (BETA)
No wrangler.toml file found. Continuing.
Detected the following tools from environment: [email protected], [email protected], [email protected], [email protected]
Installing nodejs 20.16.0
Trying to update node-build... ok
To follow progress, use 'tail -f /tmp/node-build.20250528080136.495.log' or pass --verbose
Downloading node-v20.16.0-linux-x64.tar.gz...
-> https://nodejs.org/dist/v20.16.0/node-v20.16.0-linux-x64.tar.gz
WARNING: node-v20.16.0-linux-x64 is in LTS Maintenance mode and nearing its end of life.
It only receives *critical* security updates, *critical* bug fixes and documentation updates.
Installing node-v20.16.0-linux-x64...
Installed node-v20.16.0-linux-x64 to /opt/buildhome/.asdf/installs/nodejs/20.16.0
changed 1 package in 575ms
Reshimming asdf nodejs...
Preparing [email protected] for immediate activation...
Installing python 3.12.3
From https://github.com/pyenv/pyenv
67f474d3..bfbe76e6 master -> origin/master
* [new tag] v2.6.0 -> v2.6.0
* [new tag] v2.5.5 -> v2.5.5
* [new tag] v2.5.6 -> v2.5.6
* [new tag] v2.5.7 -> v2.5.7
python-build 3.12.3 /opt/buildhome/.asdf/installs/python/3.12.3
Downloading Python-3.12.3.tar.xz...
-> https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xz
Installing Python-3.12.3...
Installed Python-3.12.3 to /opt/buildhome/.asdf/installs/python/3.12.3
Installing project dependencies: yarn
[...]
Reshimming asdf python...
INFO - Cleaning site directory
INFO - Building documentation to directory: /opt/buildhome/repo/site
INFO - Documentation built in 0.61 seconds
Finished
Checking for configuration in a Wrangler configuration file (BETA)
No wrangler.toml file found. Continuing.
Note: No functions dir at /functions found. Skipping.
Validating asset output directory
Deploying your site to Cloudflare's global network...
Uploading... (62/64)
Uploading... (63/64)
Uploading... (64/64)
✨ Success! Uploaded 2 files (62 already uploaded) (1.04 sec)
✨ Upload complete!
Success: Assets published!
Success: Your site was deployed!