kovidgoyal/kitty · warning

EBUSY

EBUSY

Error message

a temporary error occurred, try again later.

What it means

The remote clipboard peer returned status EBUSY, mapped to 'a temporary error occurred, try again later.' The selection owner is currently mid-transfer or otherwise unable to serve the request right now.

Source

Thrown at kittens/clipboard/read.go:242

		ans.WriteString(";")
		ans.WriteString(enc_payload)
	}
	ans.WriteString("\x1b\\")
	return ans.String()
}

func encode(metadata map[string]string, payload string) string {
	return Encode_bytes(metadata, utils.UnsafeStringToBytes(payload))
}

func error_from_status(status string) error {
	switch status {
	case "ENOSYS":
		return fmt.Errorf("no primary selection available on this system")
	case "EPERM":
		return fmt.Errorf("permission denied")
	case "EBUSY":
		return fmt.Errorf("a temporary error occurred, try again later.")
	default:
		return fmt.Errorf("%s", status)
	}
}

func parse_escape_code(etype loop.EscapeCodeType, data []byte) (metadata map[string]string, payload []byte, err error) {
	if etype != loop.OSC || !bytes.HasPrefix(data, utils.UnsafeStringToBytes(OSC_NUMBER+";")) {
		return
	}
	parts := bytes.SplitN(data, utils.UnsafeStringToBytes(";"), 3)
	metadata = make(map[string]string)
	if len(parts) > 2 && len(parts[2]) > 0 {
		payload, err = base64.StdEncoding.DecodeString(utils.UnsafeBytesToString(parts[2]))
		if err != nil {
			err = fmt.Errorf("Received OSC %s packet from terminal with invalid base64 encoded payload", OSC_NUMBER)
			return
		}
	}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Retry after a short delay (this status is explicitly transient)
  2. Add backoff to clipboard polling scripts (e.g. sleep 0.1–1s between attempts)
  3. Avoid issuing overlapping reads; serialize clipboard access in your tooling

Example fix

# before
for i in $(seq 20); do kitten clipboard get out.txt && break; done
# after
for i in $(seq 20); do kitten clipboard get out.txt && break; sleep 0.5; done
Defensive patterns

Strategy: retry

Validate before calling

null

Try / catch

until kitten clipboard get f 2>/dev/null; do sleep 0.5; done  # EBUSY is transient

Prevention

When it happens

Trigger: Querying the clipboard while the current owner is still converting/pasting data from the previous request; concurrent clipboard reads racing each other; the owning application temporarily blocking on its own conversion.

Common situations: Scripts polling the clipboard in tight loops; multiple kittens or tools reading simultaneously; large payloads still being transferred when a new request arrives.

Related errors


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