m1k1o/neko · error

unable to refresh file transfer list: %w

Error message

unable to refresh file transfer list: %w

What it means

Returned by Manager.Start when the initial m.refresh() of the file-transfer listing fails; refresh scans RootDir and rebuilds the shared file list, and any error there is wrapped with this message. The watcher is already running at this point, so Start aborts after the watcher goroutine was spawned.

Source

Thrown at server/internal/plugins/filetransfer/manager.go:202

					if changed {
						m.broadcastUpdate()
					}
				}
			case err := <-watcher.Errors:
				m.logger.Err(err).Msg("error in file transfer dir watcher")
			}
		}
	}()

	if err := watcher.Add(m.config.RootDir); err != nil {
		return fmt.Errorf("unable to watch file transfer dir: %w", err)
	}

	// initial refresh
	err, changed := m.refresh()
	if err != nil {
		return fmt.Errorf("unable to refresh file transfer list: %w", err)
	}
	if changed {
		m.broadcastUpdate()
	}

	return nil
}

func (m *Manager) deleteFileHandler(w http.ResponseWriter, r *http.Request) error {
	session, ok := auth.GetSession(r)
	if !ok {
		return utils.HttpUnauthorized("session not found")
	}

	enabled, err := m.isEnabledForSession(session)
	if err != nil {
		return utils.HttpInternalServerError().
			WithInternalErr(err).

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Confirm RootDir still exists and is readable by the process at startup; fix permissions or recreate the directory
  2. Retry Start — the wrapped %w error carries the underlying cause; inspect it for the exact failure
  3. Check for startup races (another process wiping/recreating the dir) and pin RootDir to a stable path
  4. If RootDir is on a network mount, ensure it is mounted before the plugin starts (init order / readiness check)

Example fix

// before (compose)
command: server start  # runs before volume mount completes

// after
volumes:
  - ./filetransfer:/var/filetransfer
depends_on:
  volume-init:
    condition: service_completed_successfully
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.ReadDir(m.config.RootDir); err != nil {
    return fmt.Errorf("root dir not listable before Start: %w", err)
}

Try / catch

var err error
for i := 0; i < 3; i++ {
    if err = m.Start(); err == nil || !strings.Contains(err.Error(), "unable to refresh file transfer list") {
        break
    }
    time.Sleep(500 * time.Millisecond) // tolerate transient dir/mount races
}
if err != nil { log.Error().Err(err).Msg("file transfer refresh failed") }

Prevention

When it happens

Trigger: Start succeeds creating and registering the watcher, then the first refresh() returns an error — e.g. the RootDir disappeared between watch registration and refresh, listing fails due to permissions, or refresh's internal file-stat/queue operations error out.

Common situations: Race where the watched directory is deleted/recreated at startup; RootDir on a flaky network mount; permission changes between watcher.Add (succeeded) and the directory read.

Related errors


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/1d65a2934b7ce1cb. Report an issue: GitHub.