kovidgoyal/kitty · warning
Too many hyperlinks, discarding hyperlinks in scrollback
Error message
Too many hyperlinks, discarding hyperlinks in scrollback
What it means
The hyperlink id pool hit HYPERLINK_MAX_NUMBER, so kitty garbage-collected hyperlinks referenced only by scrollback lines to free ids; scrollback links may stop being clickable. Rendering is unaffected.
Source
Thrown at kitty/hyperlink.c:149
_screen_garbage_collect_hyperlink_pool(screen, true);
}
hyperlink_id_type
get_id_for_hyperlink(Screen *screen, const char *id, const char *url) {
if (!url) return 0;
HyperLinkPool *pool = (HyperLinkPool *)screen->hyperlink_pool;
static char key[MAX_KEY_LEN] = {0};
int keylen = snprintf(key, MAX_KEY_LEN - 1, "%.*s:%s", MAX_ID_LEN, id ? id : "", url);
if (keylen < 0) keylen = strlen(key);
else keylen = MIN(keylen, MAX_KEY_LEN - 2); // snprintf returns how many chars it would have written in case of truncation
key[keylen] = 0;
hyperlink_map_itr itr = vt_get(&pool->map, key);
if (!vt_is_end(itr)) return itr.data->val;
if (pool->array.count >= HYPERLINK_MAX_NUMBER - 1) {
screen_garbage_collect_hyperlink_pool(screen);
if (pool->array.count >= HYPERLINK_MAX_NUMBER - 128) {
log_error("Too many hyperlinks, discarding hyperlinks in scrollback");
_screen_garbage_collect_hyperlink_pool(screen, false);
if (pool->array.count >= HYPERLINK_MAX_NUMBER) {
log_error("Too many hyperlinks, discarding hyperlink: %s", key);
return 0;
}
}
}
if (!pool->array.count) pool->array.count = 1; // First id must be 1
ensure_space_for(&(pool->array), items, hyperlink, pool->array.count + 1, capacity, 256, false);
hyperlink_id_type new_id = pool->array.count++;
pool->array.items[new_id] = dupstr(key, keylen);
if (vt_is_end(vt_insert(&pool->map, pool->array.items[new_id], new_id))) fatal("Out of memory");
// If there have been a lot of hyperlink adds do a garbage collect so as
// not to leak too much memory over unused hyperlinks
if (++pool->adds_since_last_gc > 8192) screen_garbage_collect_hyperlink_pool(screen);
return new_id;
}
View on GitHub (pinned to 6d5d0c4406)
Solutions
- Reduce unique URIs the application emits (reuse ids via OSC 8 ; id=...)
- Clear scrollback (ctrl+shift+delete / clear_terminal scrollback)
- Update kitty - pool sizing and GC heuristics improve between versions
- Report/fix the application that floods unique hyperlinks
Example fix
# before (new id minted per link) printf '\033]8;;%s\033\\%s\033]8;;\033\\\n' "$url" "$text" # after (reuse explicit id) printf '\033]8;id=u1;%s\033\\%s\033]8;;\033\\\n' "$url" "$text"
Defensive patterns
Strategy: fallback
Validate before calling
# when emitting many links, reuse an explicit id instead of minting new ones printf '\033]8;id=%s;%s\033\\%s\033]8;;\033\\' "$link_id" "$url" "$text"
Prevention
- Cache hyperlink ids per URL in your TUI app
- Offer a clear-scrollback action in long-running log viewers
When it happens
Trigger: A program emits enormous numbers of distinct OSC 8 hyperlink URIs; after garbage collection the pool is still >= MAX-128, so scrollback hyperlinks are forcibly discarded.
Common situations: Terminal apps printing a unique URL per line (log viewers, chat clients, linkify-everything tools) with large scrollback buffers.
Related errors
- Too many hyperlinks, discarding hyperlink: %s
- The value {val} is not a valid choice for underline_hyperlin
- Unknown value for show_hyperlink_targets: {x!r}
- Out of memory reading PNG file at: %s
- This must be run as kitten ask
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/5493bb345bb09cb7.
Report an issue: GitHub.