Typed search attributes

Previously, search attributes were untyped maps with string keys and interface values. This causes ambiguity on what types a search attribute key represents and leads to errors. Also, the way search attributes were created or upserted allowed mistakes to occur and was not clear to the server exactly what was expected.

  • Added TypedSearchAttributes to client.ScheduleOptions and deprecated SearchAttributes

  • Added GetTypedSearchAttributes to workflow and deprecated WorkflowInfo.SearchAttributes

  • Added UpsertTypedSearchAttributes to workflow and deprecated UpsertSearchAttributes

  • Added TypedSearchAttributes to client.StartWorkflowOptions and deprecated SearchAttributes

  • Added several new things to temporal package including:

    • SearchAttributes collection with methods and constructor

    • SearchAttributeKey and SearchAttributeUpdate interfaces

    • SearchAttributeKeyX types and constructors for typed keys



gogo/protobuf has been replaced with Google's official proto compiler.

Users may notice:

  • time.Time in proto structs will now be timestamppb.Timestamp

  • time.Duration will now be durationpb.Duration

  • V2-generated structs embed locks, so you cannot dereference them.

  • Proto enums will, when formatted to JSON, now be in SCREAMING_SNAKE_CASE rather than PascalCase.

Note on invalid UTF-8 data stored as proto strings

Prior to SDK version v1.26.0 our protobuf code generator allowed invalid UTF-8 data to be stored as proto strings. This isn't actually allowed by the proto3 spec, so if you're using our SDK and think you may store arbitrary binary data in our strings you should set -tags protolegacywhen building against our SDK.


$ go build -tags protolegacy myworker/main.go

If you see an error like grpc: error unmarshalling request: string field contains invalid UTF-8then you will need to enable this when building your code. If you're unsure then you should specify it anyways as there's no harm in doing so unless you relied on the protobuf compiler to ensure all strings were valid UTF-8.

HTTP/2 Keep Alive

HTTP/2 Keep alive is now enabled by default. This should help avoid request timeouts on previously idle connections. If users want to revert to the old behavior they can set ConnectionOptions.DisableKeepAliveCheckto false.

See also: #1299

Typed search attributes

As part of typed search attributes most old untyped search attributes API were deprecated, but will continue to function as they always have been going forward some breaking changes were required.

See also: #1368

Breaking changes include:

  • Added TypedSearchAttributes to client.ScheduleWorkflowAction and 💥removed SearchAttributes and added UntypedSearchAttributes (needed until temporalio/temporal#4787 is fixed)

Workflow Update (Experimental)

Workflow update handlers are now processed eagerly before the main workflow function instead of after. When calling workflow.SetUpdateHandlerand an update was received during that workflow task, and no other handlers have been set before, workflow.SetUpdateHandlerwill trigger the queued update handlers to run.

Activity and Workflow mock name collision in Test Suite

Fixed a bug in the workflow test suite that would cause workflow and activity mocks that shared the same name to override each other. If your test was doing this and asserting on the number of times a mock was called you may notice a change in behavior as activity and workflow mocks are now stored in separate maps.

see also: #1371

💥 Rollback Note

Due to this change in update processing , rolling back the SDK to a pre v1.26.0 version may cause workflow using workflow update (receiving update requests or registering an update handler) to get stuck with non determinism errors until they roll forward again.

Other changes

  • Tag workflow_task_execution_failedmetric with error type to help differentiate workflow task failures caused by non determinism from other task failures

  • Dump coroutine stack on deadlock timeout. When the SDK detects a deadlock it will now try to dump the stack trace of the coroutine it detected as deadlocked.

  • Add deterministic range over map helper. Iterating over Go's standard maps is not deterministic and therefore cannot be done in a workflow context. The SDK now includes helpers DeterministicKeysand DeterministicKeysFuncto get the keys of a map in a deterministic order.