Skip to content

Bug: Self-update fails with [Errno 6] No such device or address when _office desktop session is active #1665

@craig-halliday

Description

@craig-halliday

Description

The self-update process fails during the /a0/usr backup step when the _office plugin's desktop session is running. The create_usr_backup() function walks /a0/usr/ and attempts to add every file to a zip archive, but the _office plugin creates Unix socket files under /a0/usr/plugins/_desktop/ at runtime (GPG agent sockets, XDG runtime sockets). zipfile.ZipFile.write() calls open() on these sockets, which raises [Errno 6] No such device or address (ENXIO), aborting the update and rolling back.

Affected file: docker/run/fs/exe/self_update_manager.py, function create_usr_backup(), line ~374
Tested on: v1.13 attempting to update to v1.17. Likely affects any version where the _office plugin desktop session has been started.


Log excerpt (/exe/a0-self-update.log)

[2026-05-25T07:47:35Z] Saved local tracked/untracked changes into stash@{0}.
[2026-05-25T07:47:45Z] Restoring pre-update repository state after error:
  [Errno 6] No such device or address:
  '/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent.extra'
[2026-05-25T07:47:45Z] Update flow failed: [Errno 6] No such device or address: ...

Status file:

status: failed
error: '[Errno 6] No such device or address: '/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent.extra'
tag: v1.17
source_version: v1.13

Root Cause

os.walk() returns socket files (S type) in the files list. The current guard only skips broken symlinks:

# docker/run/fs/exe/self_update_manager.py ~line 365
for root, _, files in os.walk(usr_dir):
    root_path = Path(root)
    for filename in files:
        source_file = root_path / filename
        if source_file.is_symlink() and not source_file.exists():
            logger.log(f"Skipping broken symlink during usr backup: {source_file}")
            continue
        archive_name = Path("usr") / source_file.relative_to(usr_dir)
        archive.write(source_file, archive_name.as_posix())  # ENXIO on sockets

The _office plugin creates socket files in /a0/usr/ at runtime:

/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent
/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent.browser
/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent.extra
/a0/usr/plugins/_desktop/profiles/agent-zero-desktop/.gnupg/S.gpg-agent.ssh
/a0/usr/plugins/_desktop/virtual_desktop/xdg-runtime/  (dbus, xpra sockets)

Path.is_file() returns False for sockets, pipes, and device files — these should be skipped.


Relationship to #1598

Issue #1598 fixed the same function for broken symlinks. This is the same class of problem — non-regular file types that open() cannot handle — extended to live Unix sockets created by the _office plugin at runtime.


Fix

Add an is_file() guard after the existing symlink check:

if source_file.is_symlink() and not source_file.exists():
    logger.log(f"Skipping broken symlink during usr backup: {source_file}")
    continue
if not source_file.is_file():  # skip sockets, pipes, devices
    logger.log(f"Skipping non-regular file during usr backup: {source_file}")
    continue
archive_name = Path("usr") / source_file.relative_to(usr_dir)
archive.write(source_file, archive_name.as_posix())

This fix has been applied and tested locally — update from v1.13 to v1.17 completed successfully after the patch.


Steps to Reproduce

  1. Run agent-zero with the _office plugin enabled (default in Docker image)
  2. Trigger any action that starts the desktop session (e.g. open a LibreOffice document)
  3. Attempt self-update via Settings → Update
  4. Update fails; /exe/a0-self-update.log shows ENXIO on a .gnupg/S.gpg-agent.* path

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions