{
    "archive_path": "archive/1766122907.988758",
    "base_url": "matklad.github.io/2025/09/04/look-for-bugs.html",
    "basename": "look-for-bugs.html",
    "bookmarked_date": "2025-12-19 05:41",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/matklad.github.io/2025/09/04/look-for-bugs.html",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=matklad.github.io",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": null
    },
    "domain": "matklad.github.io",
    "downloaded_at": "2025-12-19T05:41:53.509642+00:00",
    "downloaded_datestr": "2025-12-19 05:41",
    "extension": "html",
    "hash": "1FW46GW4AMVFREDT95GH",
    "history": {
        "archive_org": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://web.archive.org/save/https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2025-12-19T05:43:17.507677+00:00",
                "index_texts": null,
                "output": "TimeoutExpired: Command '['/usr/bin/curl', '--silent', '--location', '--compressed', '--proxy', 'socks5://tor-socks-proxy:9150', '--head', '--max-time', '60', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)', 'https://web.archive.org/save/https://matklad.github.io/2025/09/04/look-for-bugs.html']' timed out after 60 seconds",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:17.452064+00:00",
                "status": "failed"
            }
        ],
        "dom": [
            {
                "cmd": [
                    "/usr/bin/chromium-browser",
                    "--proxy-server=socks5://tor-socks-proxy:9150",
                    "--disable-features=DarkMode",
                    "--run-all-compositor-stages-before-draw",
                    "--hide-scrollbars",
                    "--autoplay-policy=no-user-gesture-required",
                    "--no-first-run",
                    "--use-fake-ui-for-media-stream",
                    "--use-fake-device-for-media-stream",
                    "--simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT'",
                    "--headless=new",
                    "--no-sandbox",
                    "--no-zygote",
                    "--disable-dev-shm-usage",
                    "--disable-software-rasterizer",
                    "--disable-sync",
                    "--window-size=1440,2000",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "--user-data-dir=/data/personas/Default/chrome_profile",
                    "--profile-directory=Default",
                    "--dump-dom",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "131.0.6778",
                "end_ts": "2025-12-19T05:42:06.173075+00:00",
                "index_texts": null,
                "output": "output.html",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:41:56.897147+00:00",
                "status": "succeeded"
            }
        ],
        "favicon": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://www.google.com/s2/favicons?domain=matklad.github.io"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2025-12-19T05:41:56.750562+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:41:53.570688+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2025-12-19T05:41:56.813826+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:41:56.772052+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [
            {
                "cmd": [
                    "(internal) archivebox.extractors.htmltotext",
                    "./{singlefile,dom}.html"
                ],
                "cmd_version": "0.8.5rc51",
                "end_ts": "2025-12-19T05:42:12.797469+00:00",
                "index_texts": [
                    "Look Out For Bugs (/favicon.png) (/favicon.svg) (https://matklad.github.io/2025/09/04/look-for-bugs.html) (matklad) (https://matklad.github.io/feed.xml) (/css/main.css)  (/) matklad (/about.html) About (/links.html) Links (/blogroll.html) Blogroll   Look Out For Bugs Sep 4, 2025  One of my biggest mid-career shifts in how I write code was\n          internalizing the idea from this post: (https://www.teamten.com/lawrence/programming/dont-write-bugs.html) Don\u2019t Write Bugs   Historically, I approached coding with an iteration-focused mindset \u2014\n          you write a draft version of a program, you set up some kind of a test\n          to verify that it does what you want it to do, and then you just\n          quickly iterate on your draft until the result passes all the checks.  This was a great approach when I was only learning to code, as it\n          allowed me to iterate past the things which were not relevant for me\n          at that point, and focus on what matters. Who cares if it is String args or String[] args in the \u201c\u043f\u0430\u0431\u043b\u0438\u043a\n          \u0441\u0442\u0430\u0442\u0438\u043a \u0432\u043e\u0439\u0434 \u043c\u044d\u0439\u043d \u0441\u0442\u0440\u0438\u043d\u0433 \u0430-\u044d\u0440-\u0434\u0436\u0438-\u044d\u0441\u201d, it\u2019s just some obscure magic\n          spell anyway, and completely irrelevant to the maze-traversing thingy\n          I am working on!  Carrying over this approach past the learning phase was a mistake. As\n          Lawrence points out, while you can spend time chasing bugs in the freshly written code, it\n          is possible to dramatically cut the amount of bugs you introduce in\n          the first place, if you focus on optimizing that (and not just the\n          iteration time). It felt (and still feels) like a superpower!  But there\u2019s already a perfectly fine article about not making bugs, so\n          I am not going to duplicate it. Instead, I want to share a related,\n          but different super power:  You can find bugs by just reading code.   I remember feeling this superpower for the first time. I was\n          investigating various rope implementations, and, as a part of that, I\n          looked at the ImmutableText.java , the implementation\n          powering IntelliJ, very old and battle tested code. And, by just\n          reading the code, I found a bug, (https://github.com/JetBrains/intellij-community/commit/b16987177e6023cd971d22a503663b7d63691bb2) since fixed . It wasn\u2019t hard, the original code is just 500 lines\n          of verbose Java (yup, that\u2019s all that you need for a production rope).\n          And I wasn\u2019t even trying to find a bug, it just sort-of\n          jumped out at me while I was trying to understand how the code works.  That is, you can find some existing piece of software, carefully skim\n          through implementation, and discover real problems that can be fixed.\n          You can do this to your software as well! By just re-reading\n          a module you wrote last year, you might find subtle problems.  I regularly discover TigerBeetle issues by just covering this or that\n          topic on (https://www.youtube.com/watch?v=hPUL8Xo6MJw&list=PL9eL-xg48OM3pnVqFSRyBFleHtBBw-nmZ) IronBeetle : (https://youtu.be/2_IJJZFMH2M?si=oNnqd8oCckXo8OLf&t=1691) bug discovered live , (https://youtu.be/2_IJJZFMH2M?si=hluxJXQuK3XtDT3I&t=2090) fixed , (https://github.com/tigerbeetle/tigerbeetle/pull/3194) and PR merged .  Here are some tips for getting better at this: The key is careful, slow reading. What you actually are doing is\n          building the mental model of a program inside your head. Reading the\n          source code is just an instrument for achieving that goal. I can\u2019t\n          emphasize this enough: programming is all about building a precise\n          understanding inside your mind, and then looking for the diff between\n          your brain and what\u2019s in git.  Don\u2019t dodge an opportunity to read more of the code. If you are\n          reviewing a PR, don\u2019t review just the diff, review the entire subsystem. When writing code, don\u2019t\n          hesitate to stop and to probe and feel the context around. Go for git blame or git log -S to understand the\n          historical \u201cwhy\u201d of the code.  When reading, mostly ignore the textual order, don\u2019t just\n          read each source file top-down. Instead, use these two other frames:  Follow the control flow Start at main or subsystem equivalent, and use \u201cgoto\n              definition\u201d to follow an imaginary program counter.   Stare at the state Identify the key data structures and fields, and search for all\n              places where they are created and modified.    You want to see a slice across space and time, state and control flow\n          (c.f. (https://matklad.github.io/2021/04/26/concurrent-expression-problem.html) Concurrent Expression Problem  ).  Just earlier today I used the second trick to debug an issue for which\n          I haven\u2019t got a repro. I identified connection.peer = header_peer; as the key assignment that was recently introduced, then ctrl  +f  for connection.peer , and\n          that immediately revealed a gap in my mental model. Note how this was\n          helped by the fact that the thing in question, connection , was always called that in the source code! If your\n          language allows it, avoid self , use proper names.  Identify and collect specific error-prone patterns or general smells\n          in the code. In Zig, if there\u2019s an allocator and a try in\n          the same scope, (https://matklad.github.io/2025/08/16/reserve-first.html) you need to be very careful . If there\u2019s an isolated tricky\n          function, it\u2019s probably fine. If there\u2019s a tricky interaction between functions, it is a smell, and some bugs are lurking there.  Bottom line: reading the code is surprisingly efficient at proactively\n          revealing problems. Create space for calm reading. When reading, find\n          ways to build mental models quickly, this is not entirely trivial.    (https://github.com/matklad/matklad.github.io/edit/master/content/posts/2025-09-04-look-for-bugs.dj) (/assets/icons.svg#edit)   Fix typo (/feed.xml) (/assets/icons.svg#rss)   Subscribe (mailto:aleksey.kladov+blog@gmail.com) (/assets/icons.svg#email)   Get in touch (https://github.com/matklad) (/assets/icons.svg#github)   matklad     "
                ],
                "output": "htmltotext.txt",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:12.777670+00:00",
                "status": "succeeded"
            }
        ],
        "media": [
            {
                "cmd": [
                    "/usr/local/bin/yt-dlp",
                    "--restrict-filenames",
                    "--trim-filenames",
                    "128",
                    "--write-description",
                    "--write-info-json",
                    "--write-annotations",
                    "--write-thumbnail",
                    "--no-call-home",
                    "--write-sub",
                    "--write-auto-subs",
                    "--convert-subs=srt",
                    "--yes-playlist",
                    "--continue",
                    "--no-abort-on-error",
                    "--ignore-errors",
                    "--geo-bypass",
                    "--add-metadata",
                    "--format=(bv*+ba/b)[filesize<=750m][filesize_approx<=?750m]/(bv*+ba/b)",
                    "--skip-download",
                    "--cache-dir=/data/yt-dlp-cache/",
                    "--cookies=/data/yt-dlp-cache/cookies.txt",
                    "--proxy=socks5://tor-socks-proxy:9150",
                    "--no-playlist",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "2024.10.7",
                "end_ts": "2025-12-19T05:42:17.423148+00:00",
                "index_texts": [],
                "output": "media/",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:12.926885+00:00",
                "status": "succeeded"
            }
        ],
        "mercury": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/postlight-parser",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "2.2.3",
                "end_ts": "2025-12-19T05:42:12.747713+00:00",
                "index_texts": null,
                "output": "mercury/",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:09.253968+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/readability-extractor",
                    "/tmp/tmplr9hzk0q",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2025-12-19T05:42:09.047009+00:00",
                "index_texts": [
                    "Look Out For Bugs\n          Sep 4, 2025\n        \n        \n          One of my biggest mid-career shifts in how I write code was\n          internalizing the idea from this post:\n          Don\u2019t Write Bugs\n        \n        \n          Historically, I approached coding with an iteration-focused mindset \u2014\n          you write a draft version of a program, you set up some kind of a test\n          to verify that it does what you want it to do, and then you just\n          quickly iterate on your draft until the result passes all the checks.\n        \n        \n          This was a great approach when I was only learning to code, as it\n          allowed me to iterate past the things which were not relevant for me\n          at that point, and focus on what matters. Who cares if it is\n          String args or String[] args in the \u201c\u043f\u0430\u0431\u043b\u0438\u043a\n          \u0441\u0442\u0430\u0442\u0438\u043a \u0432\u043e\u0439\u0434 \u043c\u044d\u0439\u043d \u0441\u0442\u0440\u0438\u043d\u0433 \u0430-\u044d\u0440-\u0434\u0436\u0438-\u044d\u0441\u201d, it\u2019s just some obscure magic\n          spell anyway, and completely irrelevant to the maze-traversing thingy\n          I am working on!\n        \n        \n          Carrying over this approach past the learning phase was a mistake. As\n          Lawrence points out, while you\n          can spend time chasing bugs in the freshly written code, it\n          is possible to dramatically cut the amount of bugs you introduce in\n          the first place, if you focus on optimizing that (and not just the\n          iteration time). It felt (and still feels) like a superpower!\n        \n        \n          But there\u2019s already a perfectly fine article about not making bugs, so\n          I am not going to duplicate it. Instead, I want to share a related,\n          but different super power:\n        \n\n        \n          \n            You can find bugs by just reading code.\n          \n        \n        \n          I remember feeling this superpower for the first time. I was\n          investigating various rope implementations, and, as a part of that, I\n          looked at the ImmutableText.java, the implementation\n          powering IntelliJ, very old and battle tested code. And, by just\n          reading the code, I found a bug,\n          since fixed. It wasn\u2019t hard, the original code is just 500 lines\n          of verbose Java (yup, that\u2019s all that you need for a production rope).\n          And I wasn\u2019t even trying to find a bug, it just sort-of\n          jumped out at me while I was trying to understand how the code works.\n        \n        \n          That is, you can find some existing piece of software, carefully skim\n          through implementation, and discover real problems that can be fixed.\n          You can do this to your software as well! By just re-reading\n          a module you wrote last year, you might find subtle problems.\n        \n        \n          I regularly discover TigerBeetle issues by just covering this or that\n          topic on\n          IronBeetle:\n          bug discovered live,\n          fixed,\n          and PR merged.\n        \n        Here are some tips for getting better at this:\n        \n          The key is careful, slow reading. What you actually are doing is\n          building the mental model of a program inside your head. Reading the\n          source code is just an instrument for achieving that goal. I can\u2019t\n          emphasize this enough: programming is all about building a precise\n          understanding inside your mind, and then looking for the diff between\n          your brain and what\u2019s in git.\n        \n        \n          Don\u2019t dodge an opportunity to read more of the code. If you are\n          reviewing a PR, don\u2019t review just\n          the diff, review the entire subsystem. When writing code, don\u2019t\n          hesitate to stop and to probe and feel the context around. Go for\n          git blame or git log -S to understand the\n          historical \u201cwhy\u201d of the code.\n        \n        \n          When reading, mostly ignore the textual order, don\u2019t just\n          read each source file top-down. Instead, use these two other frames:\n        \n        \n          Follow the control flow\n          \n            \n              Start at main or subsystem equivalent, and use \u201cgoto\n              definition\u201d to follow an imaginary program counter.\n            \n          \n          Stare at the state\n          \n            \n              Identify the key data structures and fields, and search for all\n              places where they are created and modified.\n            \n          \n        \n        \n          You want to see a slice across space and time, state and control flow\n          (c.f.\n          Concurrent Expression Problem).\n        \n        \n          Just earlier today I used the second trick to debug an issue for which\n          I haven\u2019t got a repro. I identified\n          connection.peer = header_peer;\n          as the key assignment that was recently introduced, then ctrl\n            + f for connection.peer, and\n          that immediately revealed a gap in my mental model. Note how this was\n          helped by the fact that the thing in question, connection, was always called that in the source code! If your\n          language allows it, avoid self, use proper names.\n        \n        \n          Identify and collect specific error-prone patterns or general smells\n          in the code. In Zig, if there\u2019s an allocator and a try in\n          the same scope, you need to be very careful. If there\u2019s an isolated tricky\n          function, it\u2019s probably fine. If there\u2019s a tricky interaction\n          between functions, it is a smell, and some bugs are lurking there.\n        \n        \n        \n          Bottom line: reading the code is surprisingly efficient at proactively\n          revealing problems. Create space for calm reading. When reading, find\n          ways to build mental models quickly, this is not entirely trivial."
                ],
                "output": "readability/",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:06.309463+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://matklad.github.io/2025/09/04/look-for-bugs.html"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2025-12-19T05:42:06.218814+00:00",
                "index_texts": null,
                "output": "Look Out For Bugs",
                "pwd": "/data/archive/1766122907.988758",
                "schema": "ArchiveResult",
                "start_ts": "2025-12-19T05:42:06.207510+00:00",
                "status": "succeeded"
            }
        ],
        "wget": []
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": "TimeoutExpired: Command '['/usr/bin/curl', '--silent', '--location', '--compressed', '--proxy', 'socks5://tor-socks-proxy:9150', '--head', '--max-time', '60', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)', 'https://web.archive.org/save/https://matklad.github.io/2025/09/04/look-for-bugs.html']' timed out after 60 seconds",
        "dom": "output.html",
        "favicon": "favicon.ico",
        "git": null,
        "media": "media/",
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "Look Out For Bugs",
        "warc": null,
        "wget": null
    },
    "link_dir": "/data/archive/1766122907.988758",
    "newest_archive_date": "2025-12-19T05:42:17.452064+00:00",
    "num_failures": 1,
    "num_outputs": 8,
    "oldest_archive_date": "2025-12-19T05:41:53.570688+00:00",
    "path": "/2025/09/04/look-for-bugs.html",
    "schema": "Link",
    "scheme": "https",
    "snapshot_abid": "snp_01KCTJ1TEC347CC43601AR1H1R",
    "snapshot_id": "e8c17664-fefa-4873-9cec-247f1580c438",
    "sources": [
        "/data/sources/1766122907-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1766122907.988758",
    "title": "Look Out For Bugs",
    "url": "https://matklad.github.io/2025/09/04/look-for-bugs.html"
}