kovidgoyal/kitty · error

can't register D-Bus name: name already taken

Error message

can't register D-Bus name: name already taken

What it means

RequestName with NameFlagDoNotQueue returned a reply other than PrimaryOwner, meaning another process already owns PORTAL_BUS_NAME (org.freedesktop.impl.portal.desktop.kitty or similar) and the name cannot be acquired.

Source

Thrown at kittens/desktop_ui/portal.go:192

		interfaces = append(interfaces, prop.IntrospectData)
	}
	n := &introspect.Node{Name: object_path, Interfaces: interfaces}
	if err = conn.Export(introspect.NewIntrospectable(n), op, introspect.IntrospectData.Name); err != nil {
		return fmt.Errorf("failed to export introspected methods with error: %w", err)
	}
	return
}

func (self *Portal) Start() (err error) {
	if self.bus, err = dbus.SessionBus(); err != nil {
		return fmt.Errorf("could not connect to session D-Bus: %s", err)
	}
	reply, err := self.bus.RequestName(PORTAL_BUS_NAME, dbus.NameFlagDoNotQueue)
	if err != nil {
		return fmt.Errorf("failed to register dbus name: %v", err)
	}
	if reply != dbus.RequestNameReplyPrimaryOwner {
		return fmt.Errorf("can't register D-Bus name: name already taken")
	}
	props := PropSpec{
		"version": {Value: uint32(1), Writable: false, Emit: prop.EmitFalse},
	}
	signals := SignalSpec{
		"SettingChanged": {{"namespace", "s"}, {"key", "s"}, {"value", "v"}},
	}
	methods := MethodSpec{
		"Read":    {{"namespace", "s", false}, {"key", "s", false}, {"value", "v", true}},
		"ReadAll": {{"namespaces", "as", false}, {"value", "a{sa{sv}}", true}},
	}
	if err = ExportInterface(self.bus, self, SETTINGS_INTERFACE, DESKTOP_OBJECT_PATH, methods, props, signals); err != nil {
		return
	}
	methods = MethodSpec{
		"OpenFile": {{"handle", "o", false}, {"app_id", "s", false}, {"parent_window", "s", false}, {"title", "s", false}, {"options", "a{sv}", false},
			{"response", "u", true}, {"results", "a{sv}", false},
		},

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Find and stop the existing owner: busctl --user --list | grep portal or dbus-send to inspect, then kill the stale process
  2. Enable the portal only once per session (kitten desktop-ui enable) instead of per-window
  3. Log out/in or restart the session if a zombie process holds the name
Defensive patterns

Strategy: try-catch

Try / catch

if err := portal.Start(); err != nil {
    if strings.Contains(err.Error(), "name already taken") {
        // another instance is running; exit quietly
        return nil
    }
}

Prevention

When it happens

Trigger: Starting the desktop-ui kitten portal while another instance (or another kitty portal backend) is already running and owns the bus name.

Common situations: Two kitty sessions both launching the desktop-ui kitten; a stale portal process from a crashed session; another desktop portal backend registered under the same name.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/888e6340b7fcb4a5. Report an issue: GitHub.