apache/beam · error

execute bundle request returned error

Error message

execute bundle request returned error

What it means

fhirio's executeBundleFn.ProcessElement sends a FHIR executeBundle HTTP request via the stored FHIR client. If the transport call itself fails (network error, non-recoverable client error, context cancellation), it wraps the error with this message and emits it to the failure/dead-letter channel while incrementing the error counter, then stops processing that bundle. The pipeline does not crash; the failed bundle body is surfaced as a failure string.

Solutions

  1. Verify the FHIR store path matches projects/<p>/locations/<l>/datasets/<d>/fhirStores/<s> and that the store exists
  2. Check network connectivity to healthcare.googleapis.com from the worker (VPC/firewall/DNS, Service Networking for private access)
  3. Confirm credentials: Application Default Credentials with healthcare scope (https://www.googleapis.com/auth/cloud-healthcare)
  4. Retry failed bundles: the error is emitted to emitFailure, so collect failures and re-execute them in a follow-up step
  5. Wrap with retry/backoff for transient 5xx/network errors

Example fix

// before
emitFailure(errors.Wrap(err, "execute bundle request returned error").Error())
// after
// enable retries for transient errors before executing:
response, err := executeAndRecordLatency(ctx, &fn.latencyMs, func() (*http.Response, error) {
    return fn.client.executeBundle(fn.FhirStorePath, inputBundleBody)
})
if err != nil && isTransient(err) { return retryBundle(inputBundleBody) }
if err != nil { emitFailure(errors.Wrap(err, "execute bundle request returned error").Error()) }
Defensive patterns

Strategy: try-catch

Validate before calling

storePath := "projects/my-proj/locations/us-central1/datasets/my-ds/fhirStores/my-store"
if !strings.HasPrefix(storePath, "projects/") || strings.Count(storePath, "/") != 7 {
    return fmt.Errorf("invalid FHIR store path: %s", storePath)
}
if err := validateNetworkToHost("healthcare.googleapis.com"); err != nil { return err }

Try / catch

// process the emitFailure stream as the catch point
beam.ParDo(s, &fhirio.ExecuteBundles{...}, bundles)
// downstream: inspect emitted failure strings, filter transient causes, and re-emit for retry

Prevention

When it happens

Trigger: fn.client.executeBundle(fn.FhirStorePath, inputBundleBody) returns a non-nil error: network failure to the FHIR store, invalid FHIR store path causing HTTP client errors, request timeouts, or a cancelled context passed to executeAndRecordLatency.

Common situations: Running a Beam Go pipeline in an environment without network access to the Google Healthcare API; misconfigured FHIR store path (wrong project/region/dataset/fhirStore); missing OAuth credentials or wrong scopes; GKE/Dataflow networking/firewall rules blocking googleapis.com.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/92c44b428eca5211. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/io/fhirio/execute_bundles.go:65

	FhirStorePath string
}

func (fn executeBundleFn) String() string {
	return "executeBundleFn"
}

func (fn *executeBundleFn) Setup() {
	fn.fnCommonVariables.setup(fn.String())
	fn.successesCount = beam.NewCounter(fn.String(), baseMetricPrefix+"success_count")
}

func (fn *executeBundleFn) ProcessElement(ctx context.Context, inputBundleBody string, emitSuccess, emitFailure func(string)) {
	response, err := executeAndRecordLatency(ctx, &fn.latencyMs, func() (*http.Response, error) {
		return fn.client.executeBundle(fn.FhirStorePath, inputBundleBody)
	})
	if err != nil {
		fn.resourcesErrorCount.Inc(ctx, 1)
		emitFailure(errors.Wrap(err, "execute bundle request returned error").Error())
		return
	}

	body, err := extractBodyFrom(response)
	if err != nil {
		fn.resourcesErrorCount.Inc(ctx, 1)
		emitFailure(errors.Wrap(err, "could not extract body from execute bundles response").Error())
		return
	}

	fn.processResponseBody(ctx, body, emitSuccess, emitFailure)
}

func (fn *executeBundleFn) processResponseBody(ctx context.Context, body string, emitSuccess, emitFailure func(string)) {
	var bodyFields struct {
		Type    string `json:"type"`
		Entries []any  `json:"entry"`
	}

View on GitHub (pinned to 12126d8942)