◉ANTIGRAVITY LABJP
Articles/Tips & Best Practices
✦ Tips & Best Practices/2026-10-13Intermediate

After Dropbox Moved Under CloudStorage, Check That Your node_modules Exclusion Still Works

Dropbox's help page gives different ignore commands for the macOS File Provider build. Before handing dependency installs to an agent, here is how to check that your exclusion works: a dry-run-first shell script, and what I observed when running npm ci against a flagged directory.

antigravity462dropbox3xattrnode_modulesagent20

Before letting an agent run npm install, I decided to look at the project path again. My working folder sits under ~/Library/CloudStorage/Dropbox, and I wanted to know whether the exclusion mark I wrote about earlier could still be trusted in that location.

The honest first point: I have not been able to confirm on a Mac which mark actually takes effect on my setup. What follows is what I could verify, and how to check the rest yourself.

The help page splits macOS into two cases

Dropbox's "ignored files" help page (read in October 2026) lists two macOS variants.

SetupExample pathCommand
File Provider~/Library/CloudStorage/Dropboxxattr -w 'com.apple.fileprovider.ignore#P' 1 PATH
Not on File Provider~/Dropboxxattr -w com.dropbox.ignored 1 PATH

My earlier article only used the second row. If your folder lives under CloudStorage, it is worth asking whether the first row is the right one before repeating the old steps. The page also warns that the commands do not work if you moved the Dropbox folder away from its default location.

A few other points from the same page:

  • Online-only files, and folders containing them, cannot be ignored.
  • Anything moved into an ignored folder becomes ignored too.
  • Ignored items are removed from the server and stay only on your disk.

The last one suits regenerable things like node_modules, but I would not plan on syncing them back later.

List first, mark later

You do not need to write anything just to check. I made the script below print a list by default; nothing changes unless you pass --apply.

#!/usr/bin/env bash
# 使い方: mark-volatile.sh [--apply] <プロジェクトのパス>
set -euo pipefail
APPLY=0
if [ "${1:-}" = "--apply" ]; then APPLY=1; shift; fi
ROOT="${1:?プロジェクトのパスを指定してください}"
ROOT="$(cd "$ROOT" && pwd -P)"   # シンボリックリンクを解決した実パスで判定する
 
# CloudStorage 配下なら File Provider 版とみなす
case "$ROOT" in
  */Library/CloudStorage/*) MODE="fileprovider" ;;
  *) if [ "$(uname)" = "Darwin" ]; then MODE="legacy"; else MODE="linux"; fi ;;
esac
 
mark() {
  case "$MODE" in
    fileprovider) xattr -w 'com.apple.fileprovider.ignore#P' 1 "$1" ;;
    legacy)       xattr -w com.dropbox.ignored 1 "$1" ;;
    linux)        attr -s com.dropbox.ignored -V 1 "$1" >/dev/null ;;
  esac
}
 
# 見つけたディレクトリの中は掘り下げない(-prune)
find "$ROOT" -maxdepth 4 -type d \( -name node_modules -o -name .next -o -name Pods \
  -o -name DerivedData -o -name .gradle -o -name .swiftpm \) -prune -print |
while IFS= read -r d; do
  if [ "$APPLY" = 1 ]; then mark "$d" && echo "marked [$MODE]: $d"
  else echo "would mark [$MODE]: $d"; fi
done

What I verified:

  • A listing-only run picks up node_modules, .next and Pods, and skips src.
  • For a path containing /Library/CloudStorage/, xattr is called with com.apple.fileprovider.ignore#P (checked with a stand-in xattr that only records its arguments).
  • Running with no argument stops with an error.

What I have not verified is whether a real Dropbox on a real Mac stops syncing because of that mark. Try it on a throwaway folder first and watch the Dropbox status icon change; I will do the same before touching a real project.

Read the mark back to confirm it

A successful mark call does not prove the mark is there. Read the same attribute right after setting it.

# Read the attribute; a value of 1 means it is set
xattr -p 'com.apple.fileprovider.ignore#P' node_modules
# List every attribute on the directory
xattr -l node_modules

The syntax is ordinary xattr usage; I have not yet seen the result for the File Provider attribute name on my own machine. If nothing comes back, suspect the wrong variant and try the other attribute name.

The surprise: npm ci did not wipe the mark

In my earlier article I wrote that a clean build recreates the directory and the mark disappears (see the piece on Xcode builds breaking in a synced folder). I assumed npm ci would behave the same way.

So I tested it: a tiny project with only a local file: dependency, a user extended attribute set on node_modules, then npm ci.

  • The directory's inode was identical before and after.
  • The attribute was still there.

The conditions were npm 10.9.4, Node 22, and a Linux user xattr. That is not Dropbox's own mark, and it may not hold for the Mac xattr, other npm versions, pnpm or yarn. Still, on my side I did not need to re-mark after npm ci. Deleting the directory yourself with rm -rf node_modules does create a fresh directory, so that case needs the mark again.

A mark survives operations that keep the directory and not the ones that replace it. Check in the logs which one your agent actually uses.

Next step

Before the next time you hand dependency installs to an agent, run mark-volatile.sh without --apply and see whether node_modules appears in the list. Then mark a throwaway folder, confirm Dropbox reacts, and only then move on to the real project. As an indie developer who keeps working folders in Dropbox, that is the order I intend to follow.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

✦ Tips2026-04-25
Mastering Antigravity's Retry: How to Recover Stuck Agents Without Wasting Credits
Three Retry modes in Antigravity, how to read failure logs in 30 seconds, and a workflow that stops Retry from becoming your only fix.
✦ Tips2026-10-09
Fold Your Request into Five Lines Before You Paste the Long Notes
Pasting meeting notes straight into an agent gives you blurry results. Here is a five-line shape — goal, material, scope, finished form, check — and a small script that confirms all five lines are filled in.
✦ Tips2026-09-02
The work-root guard I run before letting an agent near several repositories
When several repositories share one machine, an agent's working root is remarkably easy to mix up. Here is a small guard that compares resolved paths, tested against seven inputs.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links