Some things you do as a developer can work for you for years, then turn around and bite you when you were least expecting. These are the things that you wish another developer had told you early in your career so you never had to make the mistakes. This post is about one of those things and if you’re reading this, consider it me telling you. File paths look like strings. You have a number of directories and maybe a file name with an extension at the end. You separate the directories and files with a ` ` character and the result looks like ` `. So you can treat them like strings, joining them or concatenating them until you pass them to another file method that is used to read from or write to the file. These were my thoughts from just a few months ago. Here’s where I was wrong. / /path/to/file Don’t forget Windows If you develop on a Mac, like I have the privilege of doing, or Linux then you might have read the above paragraph and not noticed anything wrong. If develop on Windows you probably sighed into your cup of coffee as you read the ` ` character. / It’s all too easy to forget when you work with a Mac and deploy to Linux environments, like I have done for years, that . It’s all too painful to find out you’ve made that mistake when you work on a command line tool that needs to run on both types of platform. is one such command line tool that had to go through a from things like: Windows uses backslashes create-twilio-function number of changes mkdir(path + + dirName); '/' to path = ( ); mkdir(path.join(pathName, dirName)); const require 'path' so that it would work properly on Windows. To Windows users, I’m sorry. To everyone else, when working with Node.js the is your friend. Use whenever you have to join two paths. And check out other utilities like , which returns a relative path from one path to another, and , which returns a path resolving segments like `.` or `..`. `path` module ` ` path.join ` ` path.relative ` ` path.normalize Pay no attention to , which returns a ` ` or a ` ` depending on the system you’re working on, just use ` `. ` ` path.sep / \ path.join Paths behave differently to strings To my second mistake, this time working in Ruby. This one was slightly more subtle and evaded my tests. You see, you can use the ` ` class to create fragments of paths and then concatenate them. For example: Pathname path1 = Pathname.new( ) path2 = Pathname.new( ) path1 + path2 require "pathname" "path" "to" # => #<Pathname:path/to> As you can see ` ` objects have a ` ` operator that concatenates the paths, much like ` ` concatenates strings. In fact, it also works with a mix of strings and paths: Pathname + + path1 = Pathname.new( ) path2 = path1 + path2 require "pathname" "path" "to" # => #<Pathname:path/to> This all seems well and good, except it doesn’t work the other way around. path1 = path2 = Pathname.new( ) path1 + path2 require "pathname" "to" "path" # => TypeError (no implicit conversion of Pathname into String) A nice error like that means we’ve done something wrong, that was not the problem I had though. No, the issue I had stemmed from expecting to concatenate a pathname and a string and instead concatenating two strings. This manifested itself in . You see, I was trying to create a glob of paths with the line: my Rubygem `jekyll-gzip` files = Dir.glob(dir + ) "**/*{ }" #{extensions} It turned out under some circumstances ` ` was actually a string instead of a pathname and it didn’t include a separator. So the glob was looking for ` ` when I really wanted it to look for ` `. Concatenating two pathnames or a pathname and a string will add the separator ( ), but concatenating two strings will not. This meant that the gem happily went looking for the wrong pathname, found no files and then proceeded to successfully do nothing. Replacing the entire line with: dir "dirname **/*{#{extensions}}" "dirname/** /*{#{extensions}}" as someone pointed out in a comment on my commit files = Dir.glob(File.join(dir, , )) "**" "*{ }" #{extensions} fixed the issue. In this case is the method to use to avoid surprises with strings. ` ` File.join Always use the built in path tools Whether you’re working in Node.js, Ruby, or any other language do not be tempted to treat file paths as strings. They behave differently on different platforms and mixing paths and strings together can cause hard to debug errors. Use your standard library and save yourself the hassle. Previously published at https://philna.sh/blog/2020/03/04/mistakes-treating-paths-as-strings/