{"record":{"id":"5493bb345bb09cb7","repo":"kovidgoyal/kitty","slug":"too-many-hyperlinks-discarding-hyperlinks-in-scro","errorCode":null,"errorMessage":"Too many hyperlinks, discarding hyperlinks in scrollback","messagePattern":"Too many hyperlinks, discarding hyperlinks in scrollback","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/hyperlink.c","lineNumber":149,"sourceCode":"    _screen_garbage_collect_hyperlink_pool(screen, true);\n}\n\n\nhyperlink_id_type\nget_id_for_hyperlink(Screen *screen, const char *id, const char *url) {\n    if (!url) return 0;\n    HyperLinkPool *pool = (HyperLinkPool *)screen->hyperlink_pool;\n    static char key[MAX_KEY_LEN] = {0};\n    int keylen = snprintf(key, MAX_KEY_LEN - 1, \"%.*s:%s\", MAX_ID_LEN, id ? id : \"\", url);\n    if (keylen < 0) keylen = strlen(key);\n    else keylen = MIN(keylen, MAX_KEY_LEN - 2); // snprintf returns how many chars it would have written in case of truncation\n    key[keylen] = 0;\n    hyperlink_map_itr itr = vt_get(&pool->map, key);\n    if (!vt_is_end(itr)) return itr.data->val;\n    if (pool->array.count >= HYPERLINK_MAX_NUMBER - 1) {\n        screen_garbage_collect_hyperlink_pool(screen);\n        if (pool->array.count >= HYPERLINK_MAX_NUMBER - 128) {\n            log_error(\"Too many hyperlinks, discarding hyperlinks in scrollback\");\n            _screen_garbage_collect_hyperlink_pool(screen, false);\n            if (pool->array.count >= HYPERLINK_MAX_NUMBER) {\n                log_error(\"Too many hyperlinks, discarding hyperlink: %s\", key);\n                return 0;\n            }\n        }\n    }\n    if (!pool->array.count) pool->array.count = 1; // First id must be 1\n    ensure_space_for(&(pool->array), items, hyperlink, pool->array.count + 1, capacity, 256, false);\n    hyperlink_id_type new_id = pool->array.count++;\n    pool->array.items[new_id] = dupstr(key, keylen);\n    if (vt_is_end(vt_insert(&pool->map, pool->array.items[new_id], new_id))) fatal(\"Out of memory\");\n    // If there have been a lot of hyperlink adds do a garbage collect so as\n    // not to leak too much memory over unused hyperlinks\n    if (++pool->adds_since_last_gc > 8192) screen_garbage_collect_hyperlink_pool(screen);\n    return new_id;\n}\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/hyperlink.c#L131-L167","documentation":"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.","triggerScenarios":"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.","commonSituations":"Terminal apps printing a unique URL per line (log viewers, chat clients, linkify-everything tools) with large scrollback buffers.","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"],"exampleFix":"# before (new id minted per link)\nprintf '\\033]8;;%s\\033\\\\%s\\033]8;;\\033\\\\\\n' \"$url\" \"$text\"\n# after (reuse explicit id)\nprintf '\\033]8;id=u1;%s\\033\\\\%s\\033]8;;\\033\\\\\\n' \"$url\" \"$text\"","handlingStrategy":"fallback","validationCode":"# when emitting many links, reuse an explicit id instead of minting new ones\nprintf '\\033]8;id=%s;%s\\033\\\\%s\\033]8;;\\033\\\\' \"$link_id\" \"$url\" \"$text\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cache hyperlink ids per URL in your TUI app","Offer a clear-scrollback action in long-running log viewers"],"tags":["kitty","hyperlinks","osc8","resource-limits"],"backgroundTag":"resource-pool-exhausted","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}