Monthly Archives: June 2026

Fixing LibreOffice Flatpak Opening Files from GNOME Dash

I use Fedora Silverblue with GNOME, and I have LibreOffice installed as a Flatpak.

Recently, I hit a strange problem: when searching for an office document from the GNOME Dash — for example, an .odt or .ods file in my Dropbox folder — and selecting it, LibreOffice appeared to start, but then failed with an error saying that a file like this did not exist:

The confusing part was that the file did exist at that path.

Even more confusing: if I removed the file from /run/user/1000/doc/..., the original file was removed too.

So what was going on?

The short version

The fix was:

This creates the following user override:

stored in:

After that, opening LibreOffice documents from the GNOME Dash worked again.

The setup

The system is Fedora Silverblue, so applications are mostly Flatpaks. LibreOffice is installed as:

The problematic documents live under Dropbox, for example:

Opening the same files with xdg-open worked fine:

Opening them directly with Flatpak also worked:

So LibreOffice itself was not broken.

The problem only happened when opening documents from the GNOME Dash search results.

The mysterious /run/user/1000/doc path

When GNOME opened the file from the Dash, LibreOffice complained about a path like this:

This is not a normal temporary directory.

It is part of the Flatpak / XDG document portal mechanism. The document portal exposes selected host files to sandboxed applications through a FUSE mount under:

The directory name that looks like a hash is a document portal ID.

In my case:

was the document ID.

The file under /run/user/1000/doc/... was not a copy. It was a portal-backed view of the original file. That explains why deleting it also deleted the original document.

Do not manually clean this directory with rm.

Inspecting the document portal entry

The useful command was:

It printed:

This confirmed several things:

  1. The /run/user/1000/doc/... path was a document portal path.
  2. The original file was the Dropbox file.
  3. GNOME was not launching the generic LibreOffice app ID.
  4. It was using the Writer-specific ID:

The important part is that GNOME Dash was creating a fresh portal export every time I tried to open a document.

So this was not stale recent-file history, nor was it a broken search index.

Things that did not fix it

I first tried granting LibreOffice access to my whole home directory:

That did not solve the GNOME Dash problem.

This makes sense in hindsight. The issue was not that LibreOffice could not access my Dropbox file directly. Direct opening already worked.

The issue was that GNOME Dash was giving LibreOffice this path:

not this one:

Granting access to home does not automatically make /run/user/1000/doc visible inside the Flatpak sandbox.

I also tried clearing recent files, resetting the GNOME file index, restarting portal services, and logging out and back in.

Still, every time I opened a new LibreOffice document from the Dash, a new directory appeared under:

That was the clue: GNOME was actively creating new document portal exports.

The actual fix

The working fix was to allow the LibreOffice Flatpak to see the document portal runtime directory:

Then kill any running LibreOffice instance:

After that, opening documents from the GNOME Dash worked.

The resulting override file is:

stored at:

This is much better than granting access to the whole home directory.

Why this works

GNOME Dash opens the document through the portal and passes LibreOffice a path like:

But the LibreOffice Flatpak sandbox did not have that runtime directory visible.

By granting:

we expose just the document portal mount inside the sandbox.

That is enough for LibreOffice to resolve the path that GNOME provides.

Keeping the fix in chezmoi

Since I manage my dotfiles with chezmoi, I added this file:

In chezmoi form, that is:

with this content:

That is all I need.

Useful commands

Show current LibreOffice Flatpak overrides:

Inspect a document portal entry:

Grant access to the document portal mount:

Remove the override again:

Kill LibreOffice after changing overrides:

Final result

The minimal override is:

This fixes opening LibreOffice documents from the GNOME Dash without granting LibreOffice access to the whole home directory.

The root cause appears to be this interaction:

LibreOffice was provided with a valid host-side portal path, but the sandbox could not find the corresponding runtime directory.

Granting xdg-run/doc bridges exactly that gap.

Bootstrapping chezmoi_modify_manager before chezmoi apply

If you use chezmoi_modify_manager together with chezmoi, there is one annoying bootstrap problem:

  • chezmoi_modify_manager is needed while chezmoi apply computes file contents
  • but the usual .chezmoiscripts/run_before_* hooks run too late to install it for the first apply

I wanted a solution that was:

  • automatic
  • shell-based
  • version-pinned
  • rerun only when the installer script changes

This post shows the setup I ended up with.

The problem

At first glance, it seems natural to put an installer script into .chezmoiscripts, for example, as a run_onchange_before_* script.

That helps with normal lifecycle management, but it does not solve the initial bootstrap.

Why? Because chezmoi needs to compute the target state before it runs those scripts, and modify_ files participate in that computation. If those files use chezmoi_modify_manager, then the binary must already exist before chezmoi apply reaches the script phase.

So the core issue is:

chezmoi_modify_manager must be installed before chezmoi apply starts doing the work that depends on it.

The approach

The solution is to split the problem into two:

  1. Put the installer in .chezmoiscripts as a run_onchange_before_* script, so the script is tracked by chezmoi and reruns when its contents change.
  2. Wrap chezmoi with a small shell function that manually runs that installer script before delegating to the real chezmoi apply.

That gives us the best of both worlds:

  • proper chezmoi-managed script in the source repo
  • successful first bootstrap
  • automatic reinstall when the installer changes, such as when bumping the pinned version

The installer script

I placed this file in:

~/.local/share/chezmoi/.chezmoiscripts/run_onchange_before_00-install-chezmoi-modify-manager.sh

The script is version-pinned, architecture-aware, and idempotent. It also keeps a tiny version stamp, so it can skip work when the correct version is already installed.

A few notes:

  • VERSION is deliberately hardcoded for simplicity
  • STAMP stores the installed version so the script can cheaply detect whether work is needed
  • --doctor provides a sanity check after installation

If you later want to upgrade, just change the VERSION string in the script. Because the script is a run_onchange_* script, chezmoi will detect the change.

Manual bootstrapping

After running “chezmoi init <URL>” and before running “chezmoi apply” for the first time, you must remember to manually execute this script

Alternatively, you can use the “wrapper” solution detailed next.

The wrapper

Now for the missing bootstrap step: we need to ensure the installer runs before chezmoi apply.

I used a shell function in my ~/.bashrc (or ~/.zshrc).

Then reload your shell:

With this in place, running:

does the following:

  1. finds the real chezmoi
  2. checks whether the installer script exists in the source directory
  3. runs the installer script first
  4. only then runs the real chezmoi apply

That is exactly what we need.

Why this works

This setup works because it respects the real dependency order.

The dependency is not:

“Run a script sometime before applying files.”

The dependency is:

“Ensure chezmoi_modify_manager exists before chezmoi starts evaluating anything that depends on it.”

A normal run_before_* script is still part of chezmoi’s internal apply pipeline, which is already too late for the very first bootstrap.

The shell wrapper moves the install step out of the pipeline and places it before chezmoi apply begins.

Why keep the installer in .chezmoiscripts at all?

Because it still gives you useful chezmoi behavior:

  • the installer lives in your dotfiles repo
  • it is versioned like everything else
  • changing the script content is part of your normal dotfiles workflow
  • the run_onchange_* naming still reflects the script’s intended lifecycle

In other words, the wrapper solves the bootstrap timing problem, while .chezmoiscripts keeps the implementation under chezmoi ‘s control.

Optional: ensure ~/.local/bin is on your PATH

If your shell does not already include ~/.local/bin, add it:

 

Happy dotfiles! 🙂