Nate Finch
@natefinch.bsky.social
Gopher at GitHub working on Copilot. Author of Mage. Dungeon Master and Magic player. Used to be NateTheFinch on the Bird Site that shall not be named.
The most important thing you can do when building an HTTP API is to define a json error response body and unique response codes.
HTTP status codes are *not* sufficient.
Clients need more detail to provide a good UX for users.
There are a million things that can cause a 400 Bad Request, for example.
HTTP status codes are *not* sufficient.
Clients need more detail to provide a good UX for users.
There are a million things that can cause a 400 Bad Request, for example.
November 10, 2025 at 5:39 PM
The most important thing you can do when building an HTTP API is to define a json error response body and unique response codes.
HTTP status codes are *not* sufficient.
Clients need more detail to provide a good UX for users.
There are a million things that can cause a 400 Bad Request, for example.
HTTP status codes are *not* sufficient.
Clients need more detail to provide a good UX for users.
There are a million things that can cause a 400 Bad Request, for example.
This is not the post apocalyptic RPG I was promised.
It's not in this article but the government asserts that the sandwich was thrown at "point blank range", which implies subway sandwiches have defined effective weapon ranges of varying lethality, and I would like to see the government's chart of these ranges.
Trial Begins for Man Accused of Lobbing a Sandwich at a Federal Agent www.nytimes.com/2025/11/03/u...
November 4, 2025 at 1:35 AM
This is not the post apocalyptic RPG I was promised.
This week at work, we learned about how overloading the CPU can cause your process to get killed for using too much memory.
It's unintuitive at first, but in the context of an API server, it makes sense once you think through it. Here's what was happening:
It's unintuitive at first, but in the context of an API server, it makes sense once you think through it. Here's what was happening:
October 31, 2025 at 1:44 PM
This week at work, we learned about how overloading the CPU can cause your process to get killed for using too much memory.
It's unintuitive at first, but in the context of an API server, it makes sense once you think through it. Here's what was happening:
It's unintuitive at first, but in the context of an API server, it makes sense once you think through it. Here's what was happening:
Perhaps a 🌶️ take:
Do not rely on docker / codespaces / env variables / setup scripts to make your dev environment function.
Doing a git pull should *never* break the dev experience.
Make fixes for the dev environment in-code, so that updating the code is all you need to do to continue working.
Do not rely on docker / codespaces / env variables / setup scripts to make your dev environment function.
Doing a git pull should *never* break the dev experience.
Make fixes for the dev environment in-code, so that updating the code is all you need to do to continue working.
October 24, 2025 at 5:04 PM
Perhaps a 🌶️ take:
Do not rely on docker / codespaces / env variables / setup scripts to make your dev environment function.
Doing a git pull should *never* break the dev experience.
Make fixes for the dev environment in-code, so that updating the code is all you need to do to continue working.
Do not rely on docker / codespaces / env variables / setup scripts to make your dev environment function.
Doing a git pull should *never* break the dev experience.
Make fixes for the dev environment in-code, so that updating the code is all you need to do to continue working.
Unpopular opinion on HTTP APIs - just use POST for everything and never put variables in your routes.
Spent like an hour yesterday debugging weird behavior.
Turns out, I was hitting the wrong route accidentally, because our routes overlapped in non-obvious ways.
Spent like an hour yesterday debugging weird behavior.
Turns out, I was hitting the wrong route accidentally, because our routes overlapped in non-obvious ways.
September 4, 2025 at 4:24 PM
Unpopular opinion on HTTP APIs - just use POST for everything and never put variables in your routes.
Spent like an hour yesterday debugging weird behavior.
Turns out, I was hitting the wrong route accidentally, because our routes overlapped in non-obvious ways.
Spent like an hour yesterday debugging weird behavior.
Turns out, I was hitting the wrong route accidentally, because our routes overlapped in non-obvious ways.
When designing the errors that you return to 3rd parties (whether from an API or SDK) please default to not returning sensitive data in your error messages. I've spent SO MUCH TIME handling bugs where we log customer data or return sensitive provider info from our API because of this.
August 8, 2025 at 2:59 PM
When designing the errors that you return to 3rd parties (whether from an API or SDK) please default to not returning sensitive data in your error messages. I've spent SO MUCH TIME handling bugs where we log customer data or return sensitive provider info from our API because of this.
Unpopular opinion, but the "options" pattern in Go is just bad.
The biggest problem is that it greatly hinders discoverability.
I type foo.NewBar( and my IDE shows the signature includes ...foo.BarOptions. What are the options? Dunno. I have to look through all functions in the package. #golang
The biggest problem is that it greatly hinders discoverability.
I type foo.NewBar( and my IDE shows the signature includes ...foo.BarOptions. What are the options? Dunno. I have to look through all functions in the package. #golang
July 31, 2025 at 1:51 PM
Unpopular opinion, but the "options" pattern in Go is just bad.
The biggest problem is that it greatly hinders discoverability.
I type foo.NewBar( and my IDE shows the signature includes ...foo.BarOptions. What are the options? Dunno. I have to look through all functions in the package. #golang
The biggest problem is that it greatly hinders discoverability.
I type foo.NewBar( and my IDE shows the signature includes ...foo.BarOptions. What are the options? Dunno. I have to look through all functions in the package. #golang
Saw a post on reddit about dependency injection in Go and... please don't use libraries for that stuff. DI in Go should be just "create a value in main.go, pass it to a struct that takes an interface for it. If other structs need a copy, pass it along."
That's it. That's dependency injection in go.
That's it. That's dependency injection in go.
July 30, 2025 at 1:48 PM
Saw a post on reddit about dependency injection in Go and... please don't use libraries for that stuff. DI in Go should be just "create a value in main.go, pass it to a struct that takes an interface for it. If other structs need a copy, pass it along."
That's it. That's dependency injection in go.
That's it. That's dependency injection in go.
This is 100% correct. AI isn't going to tell you that your assumptions are wrong, that product management changed their mind about that last week, that we tried that before and it doesn't work... etc.
But it is definitely like a pretty smart linter that you don't need to configure ahead of time.
But it is definitely like a pretty smart linter that you don't need to configure ahead of time.
so I like to think about AI reviews as "lint++" -- you wouldn't just commit code because tests and lint passed.
sure, it does more things than static analysis, but it still isn't going to result in someone else grokking the code at 2am.
sure, it does more things than static analysis, but it still isn't going to result in someone else grokking the code at 2am.
July 30, 2025 at 1:43 PM
This is 100% correct. AI isn't going to tell you that your assumptions are wrong, that product management changed their mind about that last week, that we tried that before and it doesn't work... etc.
But it is definitely like a pretty smart linter that you don't need to configure ahead of time.
But it is definitely like a pretty smart linter that you don't need to configure ahead of time.
Got issued new debit cards from Capital One. Noticed they were Discover branded. I thought - they're debit cards, no way they won't be accepted at places that "don't take discover" right?
Wrong!
Good job, Capital One. You've forced me to find a new bank.
Wrong!
Good job, Capital One. You've forced me to find a new bank.
July 24, 2025 at 6:57 PM
Got issued new debit cards from Capital One. Noticed they were Discover branded. I thought - they're debit cards, no way they won't be accepted at places that "don't take discover" right?
Wrong!
Good job, Capital One. You've forced me to find a new bank.
Wrong!
Good job, Capital One. You've forced me to find a new bank.
Reposted by Nate Finch
Oftentimes, the simple solution is the best one. If your traffic is fairly predictable, you don't need auto scaling, you just need a chron job that scales up during your busy times. It'll be way easier to implement, debug, and maintain.
May 2, 2025 at 3:46 PM
Oftentimes, the simple solution is the best one. If your traffic is fairly predictable, you don't need auto scaling, you just need a chron job that scales up during your busy times. It'll be way easier to implement, debug, and maintain.
Please just use ints.
If a number (like an ID or a length) should always be positive .... you should use a (signed) int.
Why? Because it prevents bugs. If you calculate a length to be -2 bytes, that's clearly a bug. If you are converting that to a uint32, it becomes 4294967294.
If a number (like an ID or a length) should always be positive .... you should use a (signed) int.
Why? Because it prevents bugs. If you calculate a length to be -2 bytes, that's clearly a bug. If you are converting that to a uint32, it becomes 4294967294.
February 11, 2025 at 4:20 PM
Please just use ints.
If a number (like an ID or a length) should always be positive .... you should use a (signed) int.
Why? Because it prevents bugs. If you calculate a length to be -2 bytes, that's clearly a bug. If you are converting that to a uint32, it becomes 4294967294.
If a number (like an ID or a length) should always be positive .... you should use a (signed) int.
Why? Because it prevents bugs. If you calculate a length to be -2 bytes, that's clearly a bug. If you are converting that to a uint32, it becomes 4294967294.
Was watching Ready Player One with the kids and I noticed one of the bombs they throw in the game was one of these and wow, core memory unlocked there. I haven't seen or thought of these in like 40 years. Evidently they're called Madballs. I'm sure I had some when I was like 8.
January 25, 2025 at 3:19 PM
Was watching Ready Player One with the kids and I noticed one of the bombs they throw in the game was one of these and wow, core memory unlocked there. I haven't seen or thought of these in like 40 years. Evidently they're called Madballs. I'm sure I had some when I was like 8.
Reposted by Nate Finch
Somebody yelled at me for posting about Ganymede instead of /the state of things/ last night.
I know we’re (almost) all on the same page here, but a Bluesky without cute cats, science facts, and dumb jokes would be bad for everyone.
I know we’re (almost) all on the same page here, but a Bluesky without cute cats, science facts, and dumb jokes would be bad for everyone.
January 24, 2025 at 5:51 PM
Somebody yelled at me for posting about Ganymede instead of /the state of things/ last night.
I know we’re (almost) all on the same page here, but a Bluesky without cute cats, science facts, and dumb jokes would be bad for everyone.
I know we’re (almost) all on the same page here, but a Bluesky without cute cats, science facts, and dumb jokes would be bad for everyone.
Anyone have tips on how to teach people to perform thorough code reviews? I am a very thorough reviewer, but I'm not sure how to teach someone else how to look for problems in a PR.
Not specific to #golang but also that is the language I am using :)
Not specific to #golang but also that is the language I am using :)
January 7, 2025 at 4:06 PM
Anyone have tips on how to teach people to perform thorough code reviews? I am a very thorough reviewer, but I'm not sure how to teach someone else how to look for problems in a PR.
Not specific to #golang but also that is the language I am using :)
Not specific to #golang but also that is the language I am using :)
This is what I've been working on recently. Full GitHub Copilot for $0 forever.
A new free tier of GitHub Copilot in Visual Studio Code.
✅ 2,000 code completions per month
💬 50 chat messages per month
💫 Models like Claude 3.5 Sonnet or GPT-4o
♥️ More fun for you
Check it out today!
Oh yeah, and we passed 150M developers on GitHub 💅 github.blog/news-insight...
✅ 2,000 code completions per month
💬 50 chat messages per month
💫 Models like Claude 3.5 Sonnet or GPT-4o
♥️ More fun for you
Check it out today!
Oh yeah, and we passed 150M developers on GitHub 💅 github.blog/news-insight...
Announcing 150M developers and a new free tier for GitHub Copilot in VS Code
Come and join 150M developers on GitHub that can now code with Copilot for free in VS Code.
github.blog
December 18, 2024 at 6:45 PM
This is what I've been working on recently. Full GitHub Copilot for $0 forever.
Me: a signed 64 bit should be good enough to store the value of an auto-increment ID
Coworker: but sometimes we ship bugs that burn through millions of IDs!
Me: <mathing> if you burned a billion IDs per second, you wouldn't exceed MAX_INT64 for 292 years
9,223,372,036,854,775,807 is *really* big
Coworker: but sometimes we ship bugs that burn through millions of IDs!
Me: <mathing> if you burned a billion IDs per second, you wouldn't exceed MAX_INT64 for 292 years
9,223,372,036,854,775,807 is *really* big
December 9, 2024 at 8:54 PM
Me: a signed 64 bit should be good enough to store the value of an auto-increment ID
Coworker: but sometimes we ship bugs that burn through millions of IDs!
Me: <mathing> if you burned a billion IDs per second, you wouldn't exceed MAX_INT64 for 292 years
9,223,372,036,854,775,807 is *really* big
Coworker: but sometimes we ship bugs that burn through millions of IDs!
Me: <mathing> if you burned a billion IDs per second, you wouldn't exceed MAX_INT64 for 292 years
9,223,372,036,854,775,807 is *really* big
Ok, so I was initially pissed that "Biden pardoned his son", but this piece from Rachel Maddow changed my mind. tl;dw - For years, the Republicans have been singling out Hunter in order to hurt Biden, and would continue to do so, with even more impunity and cruelty in the next administration.
While we're still breaking the video into social portions, here is the main thesis of last night's A block from Rachel:
youtu.be/a-9pk8_LLC0
youtu.be/a-9pk8_LLC0
December 3, 2024 at 5:59 PM
Ok, so I was initially pissed that "Biden pardoned his son", but this piece from Rachel Maddow changed my mind. tl;dw - For years, the Republicans have been singling out Hunter in order to hurt Biden, and would continue to do so, with even more impunity and cruelty in the next administration.
Wtf. Pardoning your son. You know, I was just thinking a couple weeks ago that the president really should not have the power to unilaterally overturn our judicial system. But I was thinking of Trump and the Jan 6 insurrectionists. Biden just gave Trump cover to pardon whoever the fuck he wants.
December 2, 2024 at 1:18 PM
Wtf. Pardoning your son. You know, I was just thinking a couple weeks ago that the president really should not have the power to unilaterally overturn our judicial system. But I was thinking of Trump and the Jan 6 insurrectionists. Biden just gave Trump cover to pardon whoever the fuck he wants.
Upgraded from a 2021 intel mac to the M3 an holy crap. Maybe it's just lack of cruft, but this thing feels *noticeably* faster than the old one. Opening up slack is super fast and doesn't immediately send the fan into helicopter mode.
November 20, 2024 at 1:00 AM
Upgraded from a 2021 intel mac to the M3 an holy crap. Maybe it's just lack of cruft, but this thing feels *noticeably* faster than the old one. Opening up slack is super fast and doesn't immediately send the fan into helicopter mode.
I guess I'm over here now. Thank goodness for Sky Follower Bridge letting me find all the people I followed on the bird site that shall not be named.
November 12, 2024 at 7:10 PM
I guess I'm over here now. Thank goodness for Sky Follower Bridge letting me find all the people I followed on the bird site that shall not be named.
Forgot to mention... this is what my team has been directly working on for the last... while :)
Very exciting to see it out in the wild.
Very exciting to see it out in the wild.
GitHub Copilot bringing support for more models today, including models from Anthropic and Google:
github.blog/news-insight...
github.blog/news-insight...
Bringing developer choice to Copilot with Anthropic’s Claude 3.5 Sonnet, Google’s Gemini 1.5 Pro, and OpenAI’s o1-preview
At GitHub Universe, we announced Anthropic’s Claude 3.5 Sonnet, Google’s Gemini 1.5 Pro, and OpenAI’s o1-preview and o1-mini are coming to GitHub Copilot—bringing a new level of choice to every develo...
github.blog
October 29, 2024 at 5:03 PM
Forgot to mention... this is what my team has been directly working on for the last... while :)
Very exciting to see it out in the wild.
Very exciting to see it out in the wild.
GitHub Copilot bringing support for more models today, including models from Anthropic and Google:
github.blog/news-insight...
github.blog/news-insight...
Bringing developer choice to Copilot with Anthropic’s Claude 3.5 Sonnet, Google’s Gemini 1.5 Pro, and OpenAI’s o1-preview
At GitHub Universe, we announced Anthropic’s Claude 3.5 Sonnet, Google’s Gemini 1.5 Pro, and OpenAI’s o1-preview and o1-mini are coming to GitHub Copilot—bringing a new level of choice to every develo...
github.blog
October 29, 2024 at 4:16 PM
GitHub Copilot bringing support for more models today, including models from Anthropic and Google:
github.blog/news-insight...
github.blog/news-insight...