4 ms·
is this blog post LLM generated? the explanation makes no sense: > Because the client is passing pending_delete with no value, the result of Query().Get(“pend
by blibble 8mo ago
is this blog post LLM generated?
the explanation makes no sense:
> Because the client is passing pending_delete with no value, the result of Query().Get(“pending_delete”) here will be an empty string (“”), so the API server interprets this as a request for all BYOIP prefixes instead of just those prefixes that were supposed to be removed. The system interpreted this as all returned prefixes being queued for deletion.
client:
resp, err := d.doRequest(ctx, http.MethodGet, `/v1/prefixes?pending_delete`, nil)
server:
if v := req.URL.Query().Get("pending_delete"); v != "" {
// ignore other behavior and fetch pending objects from the ip_prefixes_deleted table
prefixes, err := c.RO().IPPrefixes().FetchPrefixesPendingDeletion(ctx)
if err != nil {
api.RenderError(ctx, w, ErrInternalError)
return
}
api.Render(ctx, w, http.StatusOK, renderIPPrefixAPIResponse(prefixes, nil))
return
}
even if the client had passed a value it would have still done exactly the same thing, as the value of "v" (or anything from the request) is not used in that block
- bstsb 8mo agodoesn't look AI-generated. even if they have made a mistake, it's probably just from the rush of getting a postmortem out prior to root cause analysis
- bretthoerner 8mo ago> even if the client had passed a value it would have still done exactly the same thing, as the value of "v" (or anything from the request) is not used in that block If they passed in any value, they would have entered the block and returned early with the results of FetchPrefixesPendingDeletion. From the post: > this was implemented as part of a regularly running sub-task that checks for BYOIP prefixes that should be removed, and then removes them. They expected to drop into the block of code above, but since they didn't, they returned all routes.
- blibble 8mo agookay so the code which returned everything isn't there actual explanation: the API server by default returns everything. the client attempted to make a request to return "pending_deletes", but as the request was malformed, the API instead went down the default path, which returned everything. then the client deleted everything. makes sense now but is that explanation is even worse because that means the code path was never tested?
- jbxntuehineoh 8mo agoor they tested it, but not with a dataset that contained prefixes not pending deletion
- himata4113 8mo agoyep, no mention that re-advertised prefixes would be withdrawn again as well during the entire impact even after they shut it down.
- subscribed 8mo agoThat's weird. They only removed some 6 of our prefixes out of perhaps 40 we have with them, so something seems off in this explanation.
- PunchyHamster 8mo agobetter explanation here https://news.ycombinator.com/item?id=47106852 https://news.ycombinator.com/item?id=47106852 but in short they are changing whether string is empty, and query string "pending_delete" is same as "pending_delete=" and will return empty Or, if they specified `/v1/prefixes?pending_delete=potato` it would return "correct" list of objects to delete Or in other words "Go have types safety, fuck it, let's use strings like in '90s PHP apps instead"
- lenkite 7mo agoIf Go supported Optional's, this bug would not have surfaced.
- PunchyHamster 7mo agoYou can probably make it with generics. But if I was given option to steal one feature out of other languages it would be enums and resulting Result/Optional from Rust
- asuffield 7mo agoHi! I wrote this paragraph. I promise that I'm not an LLM, but I was in about hour 10 of my work day and I was asleep not long after writing this. Any failures in comprehensibility are from exhaustion. (Other comments have explained the bug so I won't repeat them)