Interactive startup hangs forever (blank TUI, no timeout) when a plugin marketplace dir contains macOS File Provider dataless placeholders; plus silent infinite retry on rejected API key
Claude Code bug report — interactive startup hangs forever on a plugin-marketplace directory containing macOS File Provider dataless placeholders
_Prepared 2026-08-13 (recovery session). File via /bug when convenient. All findings below are
empirical, two-sided-proven (removal cures + re-addition reproduces), from a multi-day diagnosis._
Summary
If settings.json registers a directory-source marketplace (extraKnownMarketplaces withsource.path) whose install location lives on a macOS File Provider volume (Dropbox in
CloudStorage mode), and any files in that tree are dataless placeholders while the File
Provider daemon is unhealthy, interactive claude hangs forever at startup with a fully blank
TUI — no spinner, no timeout, no error, no log line. claude -p (non-interactive) does NOT
hang, which misdirects diagnosis toward TUI/terminal config for days.
Environment
- Claude Code v2.1.228–v2.1.232, macOS Darwin 25.5.0 (Apple Silicon)
- Auth: Claude Max (keyless)
- Marketplace: directory source at
/Users/leeromsegal/Dropbox/2026 Coding/Genome/klick-ai-playbooks
(through the ~/Dropbox symlink → ~/Library/CloudStorage/Dropbox-LeeromSegal/…)
- Tree state: 273 files, of which 57 were dataless placeholders (
ls -lOshowsdataless),
while fileproviderd + the Dropbox File Provider extension were wedged (~100–200% CPU,
network counters frozen — materialization requests never serviced).
Repro
- Put a directory marketplace on a File Provider volume; evict part of it (or let the
provider keep it online-only).
- Wedge or suspend the File Provider daemon (in the wild: the Dropbox FP extension spinning
in sqlite change-enumeration; simulatable with kill -STOP on the provider extension).
- Register it in
settings.jsonunderextraKnownMarketplaces+ enable a plugin from it
in enabledPlugins.
- Launch interactive
claude→ permanent blank screen. Remove the two keys → instant paint.
Two-sided proof (bisect over full config)
- Full config → BLANK. Config minus
env/tui/hooks/statusLine(each) → still BLANK. - Config minus
enabledPlugins+extraKnownMarketplaces→ PAINTED. - Minimal config + only those two keys → BLANK. Same, with only the Dropbox-resident
marketplace entries stripped (other marketplaces kept) → PAINTED.
- Mechanism: a bare
catof one 11KB dataless file in that tree blocks >30s (unbounded);
Claude Code startup evidently performs equivalent blocking reads on the marketplace dir.
- Repointing the marketplace
source.pathto a fully-material local copy
(~/dev/klick-ai-playbooks), all other config byte-identical → PAINTED.
Why this is worth fixing
- The failure is silent and unbounded: no timeout, no stderr, no entry in
claude doctor
territory. A user whose cloud-sync daemon is unhealthy loses Claude Code entirely, with
zero pointer to the cause.
-pmode completing normally actively misleads diagnosis (looks like a TUI/terminal bug).- Dropbox/OneDrive/iCloud CloudStorage homes are common; any
.claudeasset (marketplace,
plugin, hook script) on such a volume can be a placeholder at any time.
Suggested fixes (any one would have prevented days of outage)
- Bounded reads at startup: wrap marketplace/plugin directory scans in a timeout
(even 10s), then degrade: skip the marketplace, print one warning line, continue.
- Dataless-awareness on macOS: check for
SF_DATALESS/datalessflag before open;
skip or async-hydrate rather than blocking the startup path.
- Startup phase logging: a
CLAUDE_DEBUG=startupbreadcrumb ("loading marketplace X…")
would have named the culprit in one run instead of a multi-round settings bisect.
claude doctor: flag any configured path that resolves into~/Library/CloudStorage.
Related earlier finding (same saga, distinct bug — already known internally?)
With ANTHROPIC_API_KEY exported but invalid/unfunded, claude -p silently retried forever
(rc never returned) instead of failing fast with an auth error. Keyless Max auth worked.
Fail-fast + a clear "API key auth failed" message would fix that leg.