Skip to content

Fix ReferenceError in QuickJS dispatch for unknown commands#5941

Merged
nickva merged 3 commits intoapache:mainfrom
Karthikeya1500:fix-quickjs-dispatch-referenceerror
Mar 26, 2026
Merged

Fix ReferenceError in QuickJS dispatch for unknown commands#5941
nickva merged 3 commits intoapache:mainfrom
Karthikeya1500:fix-quickjs-dispatch-referenceerror

Conversation

@Karthikeya1500
Copy link
Copy Markdown
Contributor

@Karthikeya1500 Karthikeya1500 commented Mar 25, 2026

Overview

This PR fixes a ReferenceError in the QuickJS query server dispatcher (dispatch-quickjs.js).

Previously, globalThis.dispatch executed switch (cmd.shift()) directly. If an unrecognized command was processed and triggered the default fallback block, the code attempted to format an error message referencing cmdkey, which was never defined. This caused the query server to crash and emit a JavaScript ReferenceError instead of gracefully returning the intended ["fatal", "unknown_command", ...] error array.

This fix correctly captures const cmdkey = cmd.shift(); before evaluating the switch statement. This ensures that the command name is preserved and unrecognized commands log the correct command name instead of crashing.

Testing recommendations

To test this change, you can manually send an invalid or unrecognized command payload to the QuickJS query server process (e.g. ["unknown_cmd"]).

The server should now return a properly formatted CouchDB error array logging the command ["fatal", "unknown_command", "unknown command 'unknown_cmd'"] and gracefully exit, rather than throwing a ReferenceError exception.

Related Issues or Pull Requests

N/A

Checklist

  • This is my own work, I did not use AI, LLM's or similar technology
  • Code is written and works correctly
  • Changes are covered by tests
  • Any new configurable parameters are documented in rel/overlay/etc/default.ini
  • Documentation changes were made in the src/docs folder
  • Documentation changes were backported (separated PR) to affected branches

If an unrecognized command is processed by globalThis.dispatch,
the error handler attempts to reference cmdkey without it
being defined. This throws a ReferenceError instead of generating
the intended CouchDB fatal error array.

This commit assigns cmd.shift() to a const variable cmdkey before
evaluating the switch statement.
@rnewson
Copy link
Copy Markdown
Member

rnewson commented Mar 25, 2026

Thank you for your effort but please complete our standard pull request template.

@janl
Copy link
Copy Markdown
Member

janl commented Mar 25, 2026

in addition, the correct fix is s/cmdkey/cmd/ in the default case

@Karthikeya1500
Copy link
Copy Markdown
Contributor Author

Hi @janl, thanks for taking a look!

I considered just replacing cmdkey with cmd in the default case instead of declaring the variable, but there is a catch: because cmd is an array created from JSON.parse(line), evaluating switch(cmd.shift()) removes the command name string from the array.

If we use cmd in the error string later, it will print whatever arguments remain in the array rather than the command name itself. For example, if an unknown command payload of ["unknown_cmd", "arg1"] is sent, cmd.shift() leaves cmd as ["arg1"], meaning the error would incorrectly print out unknown command 'arg1'.

I also noticed that the SpiderMonkey dispatcher in

share/server/loop.js
explicitly captures cmdkey = cmd.shift(); before evaluating for this exact reason, so my fix essentially copies that working pattern into the QuickJS dispatcher.

Let me know if that makes sense or if you prefer a different approach!

@nickva
Copy link
Copy Markdown
Contributor

nickva commented Mar 25, 2026

Thank you for your contribution @Karthikeya1500 that looks like a bug in the command error handling, indeed!

Let's add a test for this behavior to ensure we get some coverage. Since eunit tests are a bit tricky to figure out, see if this snippet would work:

diff --git i/src/couch/test/eunit/couch_js_tests.erl w/src/couch/test/eunit/couch_js_tests.erl
index 29b303ffb..ecc37d25c 100644
--- i/src/couch/test/eunit/couch_js_tests.erl
+++ w/src/couch/test/eunit/couch_js_tests.erl
@@ -38,7 +38,8 @@ couch_js_test_() ->
                 ?TDEF(should_allow_js_string_mutations),
                 ?TDEF(should_bump_timing_and_call_stats),
                 ?TDEF(should_exit_on_internal_error, 60),
-                ?TDEF(should_use_bigint)
+                ?TDEF(should_use_bigint),
+                ?TDEF(should_handle_invalid_command)
             ])
         }
     }.
@@ -465,6 +466,11 @@ should_use_bigint(_) ->
             ?assertThrow({compilation_error, _}, prompt(Proc, [<<"add_fun">>, Src]))
     end.

+should_handle_invalid_command(_) ->
+    Proc = couch_query_servers:get_os_process(<<"javascript">>),
+    BadCmd = [<<"bad">>, <<"foo">>],
+    ?assertThrow({unknown_command,<<"unknown command 'bad'">>}, prompt(Proc, BadCmd)).
+
 sample_time(Stat) ->
     couch_stats:sample([couchdb, query_server, time, Stat]).

Just curious, how did you find it? Are you building a custom indexing layer?

@Karthikeya1500
Copy link
Copy Markdown
Contributor Author

"Thanks so much for providing that snippet, @nickva! I've added your test to

couch_js_tests.erl
and pushed it up to the PR so we have the coverage down.

As for how I found it: I was actually just exploring the codebase to understand how the QuickJS dispatcher is implemented compared to the SpiderMonkey engine (

loop.js
). While I was reading through the code to understand the query server architecture, I noticed the missing cmdkey declaration in the default switch handler and realized it would throw a ReferenceError. So no custom indexing layer just yet, but I'm learning a lot about how CouchDB dispatches JS queries!"

Copy link
Copy Markdown
Contributor

@nickva nickva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@Karthikeya1500, thank you for your contribution!

@nickva nickva merged commit 322e55c into apache:main Mar 26, 2026
59 checks passed
@nickva
Copy link
Copy Markdown
Contributor

nickva commented Mar 26, 2026

While I was reading through the code to understand the query server architecture, I noticed the missing cmdkey declaration in the default switch handler and realized it would throw a ReferenceError. So no custom indexing layer just yet, but I'm learning a lot about how CouchDB dispatches JS queries!"

That's very cool. It's how often find bugs, just looking around the code or when debugging something unrelated

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.

4 participants