You ask Claude Code to fix something in page.tsx. It replies that the file does not exist. The file is open in your editor, two inches away, with unsaved changes in it.

Both of you are right. You are looking at a tab; it is looking for an address, and the address it tried was wrong.

The idea

Your project is a tree of folders on a disk, and every AI coding tool works on that tree and nothing else. It has no concept of "the file I have open" or "the project I mean". It has a and it either resolves or it does not. Almost everything confusing about this comes from the fact that the same file has more than one correct address.

text
  /Users/tim/projects/shop          <-- the project root
  |
  |-- .env.local                     hidden (leading dot), holds secrets
  |-- .gitignore                     hidden, lists what git ignores
  |-- package.json                   what this project depends on
  |-- src/
  |   |-- app/
  |   |   |-- page.tsx               <-- this file
  |   |   \-- layout.tsx
  |   \-- lib/
  |       \-- format.ts
  \-- public/
      \-- logo.svg

  Absolute address:  /Users/tim/projects/shop/src/app/page.tsx
  From the root:     src/app/page.tsx
  From src/lib:      ../app/page.tsx

How it works

  • The project root is the folder that holds package.json (and usually .git). It is the anchor everything else is measured from. When you open a folder in VS Code or Cursor, that folder is the root the editor assumes.
  • An absolute path starts at the top of the disk: /Users/tim/projects/shop/src/app/page.tsx on macOS or Linux, C:\Users\tim\projects\shop\src\app\page.tsx on Windows. It means the same thing no matter where you are.
  • A relative path is measured from wherever the program currently is, which is its . src/app/page.tsx means "starting here". .. means "one folder up".
  • The extension is the part after the last dot. .tsx is TypeScript with markup, .ts plain TypeScript, .json structured data, .md markdown, .svg an image. It tells tools how to read the contents and nothing more. Renaming styles.css to styles.txt does not change a byte inside it, but the browser stops treating it as a stylesheet.
  • A file whose name begins with a dot is a dotfile. Finder and ls hide these by default, and they are where the important configuration lives: .env.local, .gitignore, .claude/. If you have ever been told "add it to your env file" and could not find one, this is why.

What to do

  1. Say where you are before you say what is wrong. pwd prints your working directory. Run it in the terminal your assistant is running in, not a different one.
  2. Give paths from the project root, not from your editor's tab bar. src/app/page.tsx is unambiguous. "the page file" is not, and neither is page.tsx in a project with nine of them.
  3. Make hidden files visible. ls -a lists them in the terminal; in Finder, Command+Shift+Period toggles them. In VS Code they show in the sidebar already unless a setting hides them.
  4. When something is not found, check the folder before you check the code. Nine times out of ten Claude Code is one directory above or below where you think it is.

Where it breaks

Paths are not portable. A path that works on your Mac fails on a Linux server because Linux filenames are case sensitive and macOS usually is not. Header.tsx and header.tsx are the same file on your machine and two different files in production, which is a genuinely common way for a deploy to break code that ran locally.

The other trap is a file that exists but is invisible to git. Anything listed in .gitignore still sits on your disk, so your assistant may read it, edit it, and report success, while the file never reaches GitHub or your host. Configuration and secrets live exactly there.