Skip to content

fix: await Node API operations whose run() returns a non-async Promise#2659

Merged
GCHQDeveloper581 merged 2 commits into
gchq:masterfrom
roberson-io:bugfix/node-api-async-promise-ops
Jul 21, 2026
Merged

fix: await Node API operations whose run() returns a non-async Promise#2659
GCHQDeveloper581 merged 2 commits into
gchq:masterfrom
roberson-io:bugfix/node-api-async-promise-ops

Conversation

@roberson-io

Copy link
Copy Markdown
Contributor

Description

The Node API decides whether an operation is asynchronous by inspecting how its run method is declared:

// src/node/api.mjs
const isAsync = opInstance.run.constructor.name === "AsyncFunction";

A run() can return a Promise without being declared async. Those operations were treated as synchronous, so the wrapper never awaited them and the output Dish held an unresolved Promise — surfacing as Data is not a valid string: {} (Avro to JSON) or Data is not a valid ArrayBuffer: {} (Bzip2 Compress).

This affected two operations, both of which returned new Promise(...) from a plain run():

  • Avro to JSON (src/core/operations/AvroToJSON.mjs)
  • Bzip2 Compress (src/core/operations/Bzip2Compress.mjs)

The fix declares both run() methods async, which flips isAsync to true so the Node API uses its awaiting wrapper. This matches the pattern already used by several operations, including the sibling Bzip2 Decompress (async run that returns a Promise). The web UI is unaffected because src/core/Recipe.mjs already awaits every operation regardless of how run is declared, which is why the bug was Node-only.

Existing Issue

#2658

Screenshots

N/A — no visual changes.

AI disclosure

Claude Code was used to diagnose the root cause, implement the fix, and write the Node API regression tests. I have reviewed and understand all of the changes.

Test Coverage

Added two Node API regression tests in tests/node/tests/operations.mjs:

  • Avro to JSON decodes an object container file through the Node API.
  • Bzip2 Compress round-trips (compress then decompress) through the Node API.

Both tests fail on the unfixed code (the result is an unresolved Promise) and pass with the fix. The existing core-path fixtures in tests/operations/tests/AvroToJSON.mjs are unchanged and remain green. Verified locally: npm test (261 node + 2186 operation tests), npm run testnodeconsumer, npx grunt lint, and npx grunt prod all pass.

@GCHQDeveloper581 GCHQDeveloper581 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good catch!

Thanks for your contribution.

@GCHQDeveloper581
GCHQDeveloper581 merged commit df545e6 into gchq:master Jul 21, 2026
3 checks passed
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.

Bug report: Node API does not await operations whose run() returns a Promise but isn't declared async

2 participants