{"record":{"id":"e912f150cfd83a13","repo":"apache/beam","slug":"deidentifyfhirstore-operation-s-failed","errorCode":null,"errorMessage":"DeidentifyFhirStore operation (%s) failed.","messagePattern":"DeidentifyFhirStore operation \\((.+?)\\) failed\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/FhirIO.java","lineNumber":1818,"sourceCode":"        this.client = new HttpHealthcareApiClient();\n      }\n\n      @ProcessElement\n      public void deidentify(ProcessContext context) throws IOException, InterruptedException {\n        String sourceFhirStore = context.element();\n        String destinationFhirStore = this.destinationFhirStore.get();\n        DeidentifyConfig deidConfig = gson.fromJson(this.deidConfigJson, DeidentifyConfig.class);\n        Operation operation =\n            client.deidentifyFhirStore(sourceFhirStore, destinationFhirStore, deidConfig);\n        operation = client.pollOperation(operation, 15000L);\n        incrementLroCounters(\n            operation,\n            DEIDENTIFY_OPERATION_SUCCESS,\n            DEIDENTIFY_OPERATION_ERRORS,\n            RESOURCES_DEIDENTIFIED_SUCCESS,\n            RESOURCES_DEIDENTIFIED_ERRORS);\n        if (operation.getError() != null) {\n          throw new IOException(\n              String.format(\"DeidentifyFhirStore operation (%s) failed.\", operation.getName()));\n        }\n        context.output(destinationFhirStore);\n      }\n    }\n  }\n\n  /** The type Search. */\n  public static class Search<T>\n      extends PTransform<PCollection<FhirSearchParameter<T>>, FhirIO.Search.Result> {\n\n    private final ValueProvider<String> fhirStore;\n\n    Search(ValueProvider<String> fhirStore) {\n      this.fhirStore = fhirStore;\n    }\n\n    Search(String fhirStore) {","sourceCodeStart":1800,"sourceCodeEnd":1836,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/FhirIO.java#L1800-L1836","documentation":"FhirIO's deidentify step polls the DeidentifyFhirStore long-running operation and throws an IOException when the finished operation reports an error, embedding the operation name. Unlike the export path, no reason string is appended here — the developer must look the operation up (e.g. via projects.locations.operations.get) to learn why de-identification failed. The IOException allows pipeline retry/dead-letter handling to engage.","triggerScenarios":"Polling a DeidentifyFhirStore operation that completed with operation.getError() != null — commonly caused by insufficient IAM permissions on the source/destination FHIR store, an invalid deidentify config (e.g. bad TextConfig/InfoType transformations), or a source/destination store misconfiguration.","commonSituations":"De-identifying into a destination FHIR store the service account can't create/write to; misconfigured date-shift or crypto-hash config fields; regional mismatch between source and destination stores; quota exhaustion on the Healthcare API.","solutions":["Fetch the operation by name (gcloud healthcare operations describe) to see the underlying error detail and fix the reported cause","Validate the DeidentifyConfig ( transformations, dateShiftConfig) fields before running","Grant the Healthcare service agent access to both source and destination FHIR stores","Retry after transient API failures — the thrown IOException participates in Beam retry semantics"],"exampleFix":"// before\nDeidentifyConfig cfg = DeidentifyConfig.newBuilder().build(); // empty config may be invalid\n// after\nDeidentifyConfig cfg = DeidentifyConfig.newBuilder()\n    .setInfoTypeTransformations(InfoTypeTransformations.newBuilder()\n        .addTransformations(InfoTypeTransformation.newBuilder()\n            .setRedactConfig(RedactConfig.getDefaultInstance()).build()).build())\n    .build();","handlingStrategy":"try-catch","validationCode":"// validate the DeidentifyConfig structure before submitting\n Preconditions.checkNotNull(cfg.getInfoTypeTransformations(), \"deidentify transformations required\");","typeGuard":null,"tryCatchPattern":"try {\n  // run deidentify\n} catch (IOException e) {\n  if (e.getMessage().contains(\"DeidentifyFhirStore operation\")) {\n    String opName = extractOperationName(e.getMessage());\n    // describe operation to get the reason, fix config/IAM, retry\n  } else throw e;\n}","preventionTips":["Describe the failed operation via gcloud to get the hidden root cause","Validate DeidentifyConfig fields (infoTypes, dateShift, crypto hash keys) before running","Ensure IAM access to both source and destination FHIR stores"],"tags":["java","fhir","deidentify","gcp-api","permissions"],"backgroundTag":"api-error-response","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}