Skip to content

Zed goes crazy when a buffer points to a nonexistent file in /tmp/. #34864

@gwillen

Description

@gwillen

Summary

What I see in the logs:

2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:50-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:51-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:51-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:51-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"
2025-07-21T18:01:51-07:00 ERROR [worktree] failed to canonicalize root path SanitizedPath("/tmp/nonexist"): canonicalizing "/tmp/nonexist"
2025-07-21T18:01:51-07:00 WARN  [worktree] root path could not be canonicalized: canonicalizing "/tmp/nonexist"

It does this about every 5 seconds, forever, as long as I have a buffer open to a file in /tmp/ that doesn't exist. If left alone doing this long enough, the entire machine starts to get very slow, which I think is probably due to some (otherwise-unrelated) leak in Zed.

(Additionally, when I FIRST encountered this issue, it caused Zed to chew up like 100%-200% CPU, i.e. 1-2 entire cores. This was with a Zed that had been open for a long time; with a freshly-opened Zed it does not do this. I suspect this is related to some other otherwise-unrelated leak in Zed, possibly a leak of filehandles to dead processes in /proc.)

To reproduce: I think any sequence causing you to have an open buffer to a nonexistent path in /tmp/ will do, but here's one:

  • Open zed with a workspace root somewhere outside of /tmp/. (E.g. zed ~.) [I don't know if this is required.]
  • Create a file directly in /tmp/ (not in a subdirectory). (E.g. touch /tmp/foobarbaz.) [I don't know if the restriction is required.]
  • Open that file in Zed.
  • Delete the file while leaving the buffer open. (E.g. rm /tmp/foobarbaz.)

I think this may have to do with workspaces in a way where it matters that, before doing this, your current zed workspace root is somewhere outside of /tmp/. HOWEVER, I suspect putting a workspace root at /tmp/ might by itself cause Zed to go crazy in the same way (or other ways.)

Doing this results in approximately the following sequence (seen in strace), which I find very suspicious:

  • statx on /tmp/
  • readlink on /tmp/foobarbaz (doesn't exist)*
  • make a directory in /tmp/ (this only happens if the readlink fails)
  • make some files in that directory that appear to be testing the filesystem for case sensitivity
  • make various filesystem calls related to those files and that directory, then remove all of them
  • look for git repos in various places (/tmp/foobarbaz/.git, /tmp/.git, /.git), several times, as well as .gitignore files
  • try to readlink /tmp/ and the file again
  • try to open the file
  • log this failure
  • ... do this all again from the top.

For files that exist, including in /tmp/, this stops at the second line above (the readlink), never does the case sensitivity check, and there's no problem.

For files that don't exist outside of /tmp/, this whole sequence happens once, but does not repeat.

My guess is that you are putting an inotify or something on /tmp/ (as soon as /tmp/foobarbaz becomes a project root or something), and then you are self-triggering your own inotify with the case check stuff, and once that happens you go to recheck everything nearby, which causes you to notice the file isn't there, which causes you to do the case check... etc. forever until you die.

(I think this process on its own would not end the world, BUT I think there's some leak or leaks in Zed that get hit once every time through this loop, which rapidly ends the world if the loop is allowed to continue.)

Zed Version and System Specs

Zed: v0.195.5 (Zed)
OS: Linux X11 pop 22.04
Memory: 39 GiB
Architecture: x86_64
GPU: Intel(R) Graphics (RPL-U) || Intel open-source Mesa driver || Mesa 24.0.3-1pop1171163555922.04~7a9f319

Metadata

Metadata

Assignees

No one assigned

    Labels

    frequency:uncommonBugs that happen for a small subset of users, special configurations, rare circumstances, etcmeta:easy repro stepsSteps to reproduce are easyplatform:linuxhappens only on linux, not other OSpriority:P2Average run-of-the-mill bugsstaleLabel used by `stale` actionstate:needs reproNeeds reproduction steps and/or someone to reproduce

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions