{"record":{"id":"ba9029d494db3ab8","repo":"apache/iceberg","slug":"requirement-failed-current-schema-changed-expect","errorCode":null,"errorMessage":"Requirement failed: current schema changed: expected id %s != %s","messagePattern":"Requirement failed: current schema changed: expected id (.+?) != (.+?)","errorType":"exception","errorClass":"CommitFailedException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/UpdateRequirement.java","lineNumber":164,"sourceCode":"      }\n    }\n  }\n\n  class AssertCurrentSchemaID implements UpdateRequirement {\n    private final int schemaId;\n\n    public AssertCurrentSchemaID(int schemaId) {\n      this.schemaId = schemaId;\n    }\n\n    public int schemaId() {\n      return schemaId;\n    }\n\n    @Override\n    public void validate(TableMetadata base) {\n      if (schemaId != base.currentSchemaId()) {\n        throw new CommitFailedException(\n            \"Requirement failed: current schema changed: expected id %s != %s\",\n            schemaId, base.currentSchemaId());\n      }\n    }\n  }\n\n  class AssertLastAssignedPartitionId implements UpdateRequirement {\n    private final int lastAssignedPartitionId;\n\n    public AssertLastAssignedPartitionId(int lastAssignedPartitionId) {\n      this.lastAssignedPartitionId = lastAssignedPartitionId;\n    }\n\n    public int lastAssignedPartitionId() {\n      return lastAssignedPartitionId;\n    }\n\n    @Override","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/UpdateRequirement.java#L146-L182","documentation":"Thrown by AssertCurrentSchemaId.validate when the requirement's schemaId differs from base.currentSchemaId(). This requirement asserts that the table's current schema is still the one the update was planned against. A mismatch means a concurrent writer switched the current schema (SetCurrentSchema or a schema change that re-points it), so the update is rejected to avoid applying changes based on a stale schema.","triggerScenarios":"Committing updates with AssertCurrentSchemaId when base.currentSchemaId() != schemaId — another writer changed the current schema via UpdateSchema or an explicit set-current-schema operation before this commit validated.","commonSituations":"Concurrent ALTER TABLE ... SET TBLPROPERTIES ('current-schema') style operations or engine-side schema swaps; a writer that planned against schema v3 while a migration rolled the table to schema v4; REST catalog conflict between two services both evolving schema.","solutions":["Refresh metadata, read the current currentSchemaId, rebuild the requirements, and retry the commit.","If the update must target a specific schema, verify whether the new current schema still satisfies the operation; otherwise re-plan against the new schema.","Sequence schema changes through one pipeline/owner to prevent concurrent current-schema switches.","Catch CommitFailedException and retry the whole update transaction against fresh metadata."],"exampleFix":"// before\nUpdateRequirement req = new UpdateRequirement.AssertCurrentSchemaId(3); // table now at 4\n// after\ntable.refresh();\nUpdateRequirement req =\n    new UpdateRequirement.AssertCurrentSchemaId(table.schema().schemaId());","handlingStrategy":"retry","validationCode":"table.refresh();\nif (table.schema().schemaId() != expectedSchemaId) {\n  throw new IllegalStateException(\"Current schema changed; re-plan\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  commitWithRequirements(reqs);\n} catch (CommitFailedException e) {\n  if (e.getMessage().contains(\"current schema changed\")) {\n    table.refresh();\n    reqs = rebuildRequirements(table);\n  } else { throw e; }\n}","preventionTips":["Refresh metadata before building AssertCurrentSchemaId requirements","Avoid concurrent jobs that switch the current schema","Verify operation validity against the new schema after any conflict","Retry commits against refreshed base metadata rather than recycling stale requirements"],"tags":["concurrency","schema","commit-failed","iceberg"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}