Skip to content

Conversation

@39george
Copy link

Summary

When running Lapis with the cqueues server and code_cache = "off", the server can crash on the second (and subsequent) request with errors coming from lua-http/cqueues such as:

❯ lapis server --config-module config development --trace
Listening on port 8080
Environment: development
2025-12-14T18:38:30 | Info  | server starting
2025-12-14T18:38:31 | Info  | database exists already
SQL: INSERT INTO "requests" ("phone_number", "text", "name") VALUES ('some number', 'Hello world', 'Some guy') RETURNING "id"
[201] POST /request - {  }
/usr/bin/lua5.4: /home/george/.luarocks/share/lua/5.4/lapis/cmd/cqueues.lua:94: ...eorge/.luarocks/share/lua/5.4/http/connection_common.lua:8: bad argument #1 to 'strerror' (number expected, got nil)
stack traceback:
	[C]: in function 'assert'
	/home/george/.luarocks/share/lua/5.4/lapis/cmd/cqueues.lua:94: in function </home/george/.luarocks/share/lua/5.4/lapis/cmd/cqueues.lua:85>
	(...tail calls...)
	...ge/.luarocks/share/lua/5.4/lapis/cmd/cqueues/actions.lua:31: in function 'lapis.cmd.cqueues.actions.server'
	(...tail calls...)
	...e/.luarocks/lib/luarocks/rocks-5.4/lapis/dev-1/bin/lapis:4: in main chunk
	[C]: in ?

This PR changes lapis/cmd/cqueues.moon (and the generated .lua) to initialize module_reset() lazily on the first stream, instead of eagerly at server startup.

Root cause

module_reset() captures a “keep” snapshot of package.loaded at the moment it’s created. When it’s created eagerly, the keep snapshot may not include all runtime server modules (probably http.* and cqueues.*), which are later loaded as the server begins handling requests.

With code_cache = "off", reset() then clears modules that should not be reloaded. This can cause lua-http / cqueues modules to be re-required multiple times and re-apply socket.interpose(...) repeatedly, resulting in layered wrappers and mismatched return values (e.g. why becoming nil or a string). Those values eventually hit ce.strerror(why) / seterror(..., why) and crash the process.

Reproduction

I'm providing an example project which reproduces the issue: https://github.com/39george/cqueues-reset-bug

Notes

I tried to set config parameter code_cache = "app_only", but it fails too with another error:

❯ lapis server --config-module config development --trace
Listening on port 8080
Environment: development
2025-12-14T18:47:42 | Info  | server starting
2025-12-14T18:47:42 | Info  | database exists already
onstream on http.h1_stream{connection=http.h1_connection{type="server";version=1.1};state="closed"} failed: /home/george/.luarocks/share/lua/5.4/lapis/cqueues.lua:29: assertion failed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant