Repository navigation
fix(iceberg): close the gaps the post-merge inspection of #707 found - #709
Merged
Merged
Conversation
- CLI output keeps square brackets: validate messages, CLIError context and suggestions, and FluidCLIError.format_for_user print literally (Rich ate exposes[orders]); printed tofu state rm commands stay on one line. - Runners check the sink they push: one iceberg_sink_plan gate shared by the validator, the preflight and both runners; hand-written configs are preflighted; each runner reads the build it executes, not builds[0]. - GCP: an Iceberg sink target with no location.catalog is refused (sink REST vs dbt-bigquery/GCP IaC BigLake); a sink.catalog/hand-written type that reaches BigLake is not a split. - catalog: bigquery on Kafka Connect warns (sink 1.9.2 has no bigquery type); runtime warnings follow the catalog type that reaches the worker. - Unknown catalog values: the native AWS planner refuses them like the IaC, without a plan_failed log line; a typo no longer also draws a Lake Formation refusal. - Catalog-move guard: a Glue database is flagged only when the moved expose's own table is in state; Snowflake external volumes are guarded too; probe failures log at WARNING; wiring proven by behaviour tests through apply_via_opentofu. - Agreement matrix extended to the planner, policy compiler, Confluent and dbt-BigQuery.
fas89
had a problem deploying
to
integration-emulated
October 7, 2026 10:56 — with
GitHub Actions
Failure
…atalog-move error to its docs The upgrade note named rest/iceberg_rest/polaris/unity/nessie as having had a Snowflake EXTERNAL VOLUME; they never did (the pre-#707 external set). The kinds that lost one are lakekeeper, bigquery, the iceberg-rest spelling, hive, jdbc, hadoop and dynamodb, which is what the guard checks. iceberg_catalog_move_blocked was not in the error catalog, so the CLI printed no docs link for it; it now links the guard's section in cli/apply.
fas89
had a problem deploying
to
integration-emulated
October 7, 2026 11:13 — with
GitHub Actions
Failure
…catenation in the catalog-move guidance
- Catalog-move guard: a moved Iceberg expose that names no table had its v0.19.0 Glue database planned for destroy (the evidence rule needed a table); a database is now flagged when the expose's own table is in state OR the expose names no table. The shared-database false positive stays fixed. - Snowflake guard: the old volume is found by its contract-derived name, so an upgrade that also set location.warehouse to a catalog name or dropped iam_role_arn is still stopped. - GCP split gate: keyed on the catalog that reaches the worker, so a sink that reaches Glue/DynamoDB through catalog-impl (sink.catalog: glue, hand-written catalog-impl) is refused like a REST one. - A hand-written sink config or override whose type/catalog-impl selects a different catalog than the expose's is an error on every platform (following the GCP remedy while a hand-written config wrote REST used to pass). Catalog impl class names checked against apache/iceberg CatalogUtil.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This fixes the P2 findings from the post-merge inspection of #707 (one catalog-kind table for every emitter). The inspection was a world-class review across docs, codebase/security, tests and architecture, with every finding checked by an adversarial verifier and the CLI UX walked by hand. All findings below were reproduced first and are covered by tests that fail without the fix.
[...]fluid validateprintedexposes declares governance.lakeFormation, bundle findings lost[error], andpip install 'pkg[gcp]'lost its extra.FluidCLIError.format_for_userprint literally.tofu state rm <address>stays on one line.sink_connector_configthat validate refused was still deployed.iceberg_sink_plan, shared by the validator, the preflight and both runners. Hand-written configs are checked before anything is created.build_id, but the runners readbuilds[0]properties.executing_build).catalog: bigqueryon Kafka Connecttype=bigquery, which sink 1.9.2 cannot load. Silent.apply_via_opentofufor AWS and Snowflake. Probe failures log at WARNING.CatalogMoveSpec. Snowflake volumes are guarded withtofu state rmremediation.catalog: gluplanned buckets and no Glue table.UnknownIcebergCatalogErrorand noplan_failedlog line. A typo no longer also draws a Lake Formation refusal.P3 findings, plus the out-of-scope defects the reviewers found (the meltano, dlt and airbyte runners also read
builds[0], among others), are filed on Trello.Type of Change
The breaking change: a GCP Iceberg expose that a streaming sink writes to must now name its catalog. It is called out in the CHANGELOG upgrade notes, with the remedy.
Documentation
exposes[<id>], GCP error, bigquery warning, Snowflake guard and upgrade path, exact preflight scope, Snowflake ownership sentence narrowed, troubleshooting rows)Checklist
pytest) — 4 local-environment failures fail identically onmain, see Testingruff checkandblack(24.10.0) with no errorsTesting
-n 8 --dist loadscope):20905 passed, 556 skipped. Four tests fail locally, and they fail identically onmain(9acc511d):tests/iac/test_iac_moto_e2e.py(×3): Glue catalog id under OpenTofu 1.12 and a newer moto. A separate fix is in progress.tests/test_coding_agent_live.py: localclaudeCLI; not run in CI.ruff,black --check(24.10.0) andscripts/mypy_strict.pyare clean.plan_failedline;9acc511d..b87fd3a7: no findings.Fixed before merge: defect scan of this PR
A defect scan of this branch (41 agents across static, dynamic and CLI-journey lanes, each finding checked by a skeptic) found four gaps in this PR's own checks. All four are fixed here, each with a reproduce-first test and a mutation-killed regression test:
location.warehouseor droppediam_role_arn. It now finds the volume by its contract-derived name, which a test pins to the emitter's own key.catalog-impl: the gate missed sinks that reach their catalog throughcatalog-impl, such assink.catalog: glueor a hand-written impl. It now keys on the catalog that reaches the worker.type/catalog-implthat selects a different catalog than the expose's is now an error on every platform. Following the GCP remedy while a hand-written config wrote REST used to pass. Glue's Iceberg REST endpoint users declarecatalog: rest.The catalog impl class names were checked against apache/iceberg
CatalogUtil.The other 21 confirmed defects, including one pre-existing High (a streaming sink always writes the first Iceberg expose), are filed on Trello.
Full suite after the fixes:
20947 passed, 555 skipped. The same 4 local-environment failures fail identically onmain.Tested live
The real
fluidCLI built from this branch: