Here is a summary of the mistakes made during the transition from curl process spawning to Zig's native std.http.Client, and lessons learned for future agents working in this repository.
- Mistake: Assuming the structure of Zig's
std.http.Clientbased on older versions (e.g., trying to useclient.open(),req.start()). - What I should have known: The Zig standard library API changes rapidly across releases. Before exploring HTTP clients in Zig, I should have immediately checked the local Zig standard library source code (e.g., viewing
std/http/Client.zig) to confirm signatures for request and response interfaces instead of relying on trial-and-error with the compiler.
- Mistake: Encountering "invalid JSON" errors after migrating from
curltostd.http.Client. I initially assumed my parsing logic was broken. - What I should have known: By default, Zig's
std.http.Clientrequests include the headerAccept-Encoding: gzip, deflate. The OpenAI endpoints honored this and returned compressed binary payloads, causing the application's JSON parser to fail. When working with plain JSON endpoints in Zig without a decompression pipeline, it is critical to disable this header explicitly in the RequestOptions:.accept_encoding = .omit.curldefaults differently and sidestepped this issue natively.
- Mistake: Trying to use
client.fetch(FetchOptions)with a.response_writerbound to anstd.ArrayList(u8).writer().any(). This resulted in obscureIo.DeprecatedWriterpointer cast issues during compilation. - What I should have known: Zig has been overhauling its
std.io.Writertyping system. Some high-level generic APIs likeclient.fetchcan have rough edges when dynamically typing writers in recent versions. The most stable and predictable networking pattern is to use the low-level HTTP flow instead:client.request(...)req.sendBodiless()orreq.sendBodyUnflushed(...)req.receiveHead(&buffer)response.reader().appendRemaining(allocator, &array_list, limits)
- Mistake: Mixing up
.init(allocator)with.emptywhen declaring array lists for the HTTP headers. - What I should have known: If an array list is initialized with
.empty, it behaves like an unmanaged data structure and implicitly expects theallocatorto be passed during mutations (e.g.,list.append(allocator, item)). Attempting to use.append(item)on it will raise a compilation error regarding missing initialization struct members.
- Mistake: Writing multiple test blocks in
src/rpc.zig, importing it in the rootrpc_tests.zigvia_ = @import("src/rpc.zig");, and expectingzig build testto run all 8 tests. It resulted in only 1 test tracking. - What I should have known: Zig's test runner only explores the test blocks that are referenced or reachable from the root file. To recursively discover and run tests defined in imported files, you MUST use
std.testing.refAllDecls(@import("your_file.zig"));.
- Mistake: Underestimating what
--data-urlencodedoes behind the scenes incurl. - What I should have known:
curldoes heavy lifting regardingapplication/x-www-form-urlencodedpayloads and safely converting key-value pairs into form strings. Zig does not have a comprehensive, single-function form serializer in the standard library. I should have anticipated needing to write anappendUrlEncodedfunction manually from the start rather than trying to figure outcurlmappings implicitly.