Skip to content

chore(proto)!: bump protobufjs to v8 and protobufjs-cli to v2 - #2303

Open
mjameswh wants to merge 6 commits into
mainfrom
bump-protobufjs
Open

chore(proto)!: bump protobufjs to v8 and protobufjs-cli to v2#2303
mjameswh wants to merge 6 commits into
mainfrom
bump-protobufjs

Conversation

@mjameswh

@mjameswh mjameswh commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrades protobufjs 7.6.4 -> 8.7.1 and protobufjs-cli 1.x -> 2.6.1.

This major version bump resolves multiple issues we had previously, allowing cleaning up various workarounds from our code base:

  • Drop our local pnpm patch on protobufjs. The parser bug has been fixed upstream (fix: Parse aggregate objects in option arrays protobufjs/protobuf.js#2379).
  • proto3-json-serializer is replaced by protobufjs/ext/protojson. proto3-json-serializer has no protobufjs 8 support and no prospect of it.
  • protobufjs's extension is spec-compliant out of the box, removing the need for fixPayloads, fixBuffers, and the Buffer global shimming inside the sandbox.
  • replaceBuffers had to stay, but is now skipped outright if Buffer is absent (e.g. in the Workflow sandbox).
  • The webpack fs shim for protobufjs is gone, since v8's src/util/fs.js uses require(/* webpackIgnore: true */ "fs"). That comment only takes effect with module.parser.javascript.commonjsMagicComments, which is now enabled in the bundler.
  • protobufjs now properly defines its dependency to long, so injection of that dependency (in protos/root.js) goes away.

This has some visible consequences on generated protobuf types, which are exposed as part of @temporalio/proto. See details in CHANGELOG.md.

@mjameswh
mjameswh requested review from a team as code owners August 10, 2026 16:12
mjameswh and others added 4 commits August 10, 2026 13:36
…decode too

The breaking change entry framed the omission of default-valued fields as a
ProtoJSON concern, but protobufjs 8 also stops materializing them when decoding
binary payloads and in fromObject. What changes is own-property enumeration —
Object.keys, spreads and deep equality — rather than reading the field, which
still yields the default.
The features suite on main still uses proto3-json-serializer and pins
protobufjs 7, which is incompatible with this change. Point the job at
temporalio/features#863 until that PR merges, then revert this.
Comment thread .github/workflows/ci.yml
Comment thread CHANGELOG.md
Comment on lines +42 to +43
- The `getTypeUrl` method on generated message types is no longer declared, though it remains
callable at runtime.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we want to advertise that it is still callable? If it is no longer declared could it be removed upstream without it being considered a breaking change?

Comment thread packages/test/src/test-nexus-update-operation.ts
const systemInfo = await temporalnexus
.getClient()
.connection.workflowService.getSystemInfo({ namespace: 'default' });
const systemInfo = await temporalnexus.getClient().connection.workflowService.getSystemInfo({});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this releated to the protobuf bump?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's a latent bug that the protobufjs bump exposed.

There's actually no namespace property on IGetSystemInfoRequest, so the former was technically incorrect, but TSC was not reporting this as an error given the previous definition of that type. It is now, so I had to remove the extraneous property.

ContinueAsNewInitiator.CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED
);
const initiator = hist.events?.[0].workflowExecutionStartedEventAttributes?.initiator;
t.true(initiator === undefined || initiator === ContinueAsNewInitiator.CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What are the situations where it is undefined vs being a set value? Does the assertion need to handle both?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

With protobufjs v8, fields no longer fills default values for unset fields. That's in line with how protobuf works in other language.

In this case, CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED is the default value for the initiator. So in v7, protobufjs guaranteed that initiator would be CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED if not explicitly set in the serialized message. In v8, it would be undefined in that case. But it could be CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED if the value was specifically set in the message.

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.

2 participants