{"record":{"id":"10c9ae00e1d4e40c","repo":"apache/beam","slug":"msg","errorCode":null,"errorMessage":"${msg}","messagePattern":"\\$\\{msg\\}","errorType":"http","errorClass":"GoogleJsonResponseException","httpStatus":412,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/testing/FakeDatasetService.java","lineNumber":441,"sourceCode":"        throwNotFound(\"Tried to get a table %s, but no such table existed\", tableReference);\n      }\n      checkSchemaChanges(tableContainer.table.getSchema().getFields(), tableSchema.getFields());\n      tableContainer.table.setSchema(tableSchema);\n\n      for (Stream stream : writeStreams.values()) {\n        if (stream.tableContainer == tableContainer) {\n          stream.setUpdatedSchema(tableSchema);\n        }\n      }\n    }\n  }\n\n  @FormatMethod\n  void checkSchemaPredicate(boolean predicate, String msgFormat, Object... args)\n      throws IOException {\n    String msg = String.format(msgFormat, args);\n    if (!predicate) {\n      throw new GoogleJsonResponseException(\n          new HttpResponseException.Builder(\n              HttpStatusCodes.STATUS_CODE_PRECONDITION_FAILED, msg, new HttpHeaders()),\n          null);\n    }\n  }\n\n  private void checkSchemaChanges(\n      List<TableFieldSchema> oldSchema, List<TableFieldSchema> newSchema) throws IOException {\n    List<com.google.cloud.bigquery.storage.v1.TableFieldSchema> oldSchemaProtos =\n        oldSchema.stream()\n            .map(TableRowToStorageApiProto::tableFieldToProtoTableField)\n            .collect(Collectors.toList());\n\n    List<com.google.cloud.bigquery.storage.v1.TableFieldSchema> newSchemaProtos =\n        newSchema.stream()\n            .map(TableRowToStorageApiProto::tableFieldToProtoTableField)\n            .collect(Collectors.toList());\n    checkSchemaChangesProtos(oldSchemaProtos, newSchemaProtos);","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/testing/FakeDatasetService.java#L423-L459","documentation":"checkSchemaPredicate throws a GoogleJsonResponseException with HTTP 412 Precondition Failed when the predicate is false. It is the fake's way of reporting BigQuery precondition failures (typically schema conflicts) with a caller-supplied message.","triggerScenarios":"checkSchemaChangesProtos detecting an incompatible schema change (e.g. modifying a REQUIRED/REPEATED field, changing a field type) via update/patch table schema calls.","commonSituations":"Tests or code updating a table schema in a way BigQuery would reject: narrowing a field type, making an optional field required, changing mode.","solutions":["Make the schema change BigQuery-compatible (add optional fields, never change/remove existing field types or modes)","Fetch the current table schema first and merge the new fields with the existing ones","Catch GoogleJsonResponseException and inspect the 412 status plus message to identify the violated precondition"],"exampleFix":"// before\nschema.update(Set.of(Field.newBuilder(\"f\", LegacySQLTypeName.INTEGER).build())); // 412\n// after\n// keep existing field 'f', only add new nullable fields\nTableSchema merged = mergeFields(existingSchema, newFields);\nservice.updateTableSchema(tableRef, merged);","handlingStrategy":"try-catch","validationCode":"// Compare your new schema against the fetched one before updating\nTable current = service.getTable(tableRef);\nfor (Field f : newFields) {\n  Field existing = current.getSchema().getFields().stream()\n      .filter(x -> x.getName().equals(f.getName())).findFirst().orElse(null);\n  if (existing != null && (existing.getType() != f.getType() || existing.getMode() != f.getMode())) {\n    throw new IllegalArgumentException(\"illegal schema change on field: \" + f.getName());\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  service.updateTableSchema(tableRef, newSchema);\n} catch (GoogleJsonResponseException e) {\n  if (e.getStatusCode() == 412) {\n    throw new SchemaPreconditionFailedException(e.getDetails(), e);\n  }\n  throw e;\n}","preventionTips":["Only add nullable fields; never alter existing field types or modes","Fetch and merge current schema before update","Test schema migrations against the fake before running against real BigQuery"],"tags":["bigquery","schema","precondition-failed","http-412"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}