Tip

  1. Need help? Please let us know in the SUEWS Community.

  2. Please report issues with the manual on GitHub Issues (or use Report Issue for This Page for page-specific feedback).

  3. Please cite SUEWS with proper information from our Zenodo page.

YAML Configuration Schema Versioning#

Note

Schema versioning was introduced in SUEWS v2025.8 to track changes to the YAML configuration structure independently of model code releases. The concrete version labels use SUEWS’ CalVer convention (YYYY.M), aligned with the release that first shipped each shape.

Schema Versioning Overview#

SUEWS YAML configurations carry a schema_version field that tracks the structure and format of the configuration file:

  • Tracks structure only: schema versions change when public fields are added, removed, renamed, restructured, or have their type changed.

  • Independent of model versions: SUEWS can ship many model updates without disturbing the schema; conversely one schema version usually spans several model releases.

  • Enables migration: each transition is backed by a concrete migration handler that upgrades older YAMLs to the current shape.

  • Simplifies compatibility checks: a single label, not a compatibility matrix.

Schema version is distinct from the SUEWS model version. A line such as schema_version: "2026.5" describes the shape of the configuration file, while the SUEWS version you installed (for example 2026.4.3) describes the model code. One schema may validate many model releases.

Schema Version Field#

Add the schema_version field to the top level of your configuration:

name: my_urban_config
schema_version: "2026.5"
description: Urban climate simulation for central London
model:
  # ... model configuration ...
sites:
  # ... site configuration ...

If no schema_version is specified, SUEWS assumes the current schema version and suppresses the compatibility warning. For reproducible runs you should always set the field explicitly so future readers can tell which shape the file targets.

Schema Version Policy#

Schema labels use CalVer (YYYY.M, occasionally YYYY.M.D), aligned with the SUEWS release in which that shape first shipped. The next label is chosen from the current month, not incremented as a floating-point number — 2026.5 comes after 2026.4, which comes after 2026.1, which comes after 2025.12.

A bump happens when a PR to src/supy/data_model/ makes a previously valid user YAML no longer round-trip. In practice that means any of:

  • a public field is renamed (for example DeepSoilTemperatureAnnualMeanAirTemperature)

  • a public field is removed (for example MinimumVolumeOfDHWinUse)

  • a public field changes type or shape (scalar becomes profile dict; optional becomes required-with-no-default)

  • a new required field without a sensible default is added

  • a nested section is restructured (split, merged, or re-keyed)

  • an enum or literal is tightened so that a previously accepted value is now rejected

Additive, backward-compatible changes (new Optional fields with defaults, new output variables, tightened validator ranges) do not bump the schema — the YAML shape is unchanged.

Important

Schema versions change when the code needs them to. If you are pinning to a specific SUEWS release, pin schema_version to the label listed for that release in the version history below.

Compatibility Checking#

SUEWS checks schema compatibility when loading a configuration. Compatibility is derived from the migration handler registry (supy.util.converter.yaml_upgrade._HANDLERS) rather than a static compatibility table: a version is compatible with the current one if and only if it equals the current version or a (config_version, current_version) handler is registered. Adding a handler is what makes the previous schema compatible; there is no separate table to update (gh#1304).

The three outcomes users see:

Current version

Configuration loads with no warning.

Older schema with a registered migration
Configuration uses schema 2026.4, current is 2026.5 (compatible)

The YAML loads via the chained migration. Regenerate the file with SUEWS Format Converter if you want to persist the upgrade.

Older schema with no registered migration
WARNING: Configuration uses older schema 2025.8, current is 2026.5.
Consider updating your configuration.
Newer schema than this SUEWS knows about
WARNING: Configuration uses newer schema 2027.1, this version supports 2026.5.
Please update SUEWS or use an older configuration.

Migration#

When schema versions change, migration tools upgrade existing YAMLs to the current shape. See Transitioning to YAML-based Configuration for a user-facing walk through of each release’s delta, and SUEWS Format Converter for conversions that combine version migration with legacy table-to-YAML rewriting.

Command-line migration (preferred entry point)#

# Upgrade a YAML to the current schema in place-safely (creates a .bak)
suews schema migrate old_config.yml

# Migrate to a specific target schema
suews schema migrate config.yml --target-version 2026.5

# Dry-run to preview the rename/drop deltas
suews schema migrate config.yml --dry-run

Python API#

from supy.data_model.schema.migration import SchemaMigrator

migrator = SchemaMigrator()
upgraded = migrator.migrate(old_config, to_version="2026.5")

from supy.data_model.schema.version import is_schema_compatible
if is_schema_compatible("2026.4"):
    print("2026.4 has a registered migration path to current")

Version History#

The lineage below mirrors SCHEMA_VERSIONS in src/supy/data_model/schema/version.py. Each release tag maps to the schema that shipped with it via supy.util.converter.yaml_upgrade._PACKAGE_TO_SCHEMA.

Schema 2026.5 (current; released with 2026.6.5)

The single released schema collapsing the 2026.5.dev1 .. 2026.5.dev14 development cycle. A single (2026.4 -> 2026.5) handler in src/supy/util/converter/yaml_upgrade.py::_HANDLERS applies the union of every dev-cycle delta, logging each rename and drop. The union of breaking changes against 2026.4 is:

  • Fused field names to snake_case (#1256, Category 1): for example netradiationmethod -> net_radiation_method, soildepth -> soil_depth, baset -> base_temperature, crwmax -> water_holding_capacity_max, and 55 more across ModelPhysics, SurfaceProperties, LAIParams, VegetatedSurfaceProperties, EvetrProperties, DectrProperties and SnowParams.

  • ModelPhysics selector renames (#1321): the _method / _model suffixes are dropped and domain abbreviations expanded, giving net_radiation, storage_heat, emissions, stability, water_use, roughness_sublayer, frontal_area_index and surface_conductance.

  • STEBBS YAML fully snake_case (#1334, #1337, #1327): the PascalCase exception is retired (124 renames across building_archetype, stebbs and snow), and the hot-water subsystem is unified under hot_water_* (the opaque dhw_* prefix is dropped).

  • Naming-convention reorder (#1392, #1394, #1452): field names are reordered quantity-first (wall_external_thickness -> thickness_wall_outer), the archetype_* namespace prefix is applied to whole-archetype fields, and building_type is dropped.

  • ``model.control`` restructure (#1372, #1420): forcing_file -> forcing.file and output_file -> output (inner path -> dir; the legacy string form is removed). Per-land-cover lai_<surface> / wuh_<surface> forcing columns are now accepted.

  • STEBBS physics nested (#1456): the flat model.physics STEBBS switches fold under model.physics.stebbs (stebbs.enabled + stebbs.parameters; capacitance, setpoint, same_albedo_* and same_emissivity_* move at their leaf names).

  • ``frontal_area_index`` selector (#1495): reduced to observed / modelled; the provided, use_provided and simple_scheme aliases are retired.

Legacy YAMLs continue to load through the Pydantic backward-compat shims with a DeprecationWarning; bridge DataFrame / Fortran column names are unchanged, so there is no model-output change versus 2026.4 (shipped with 2026.4.3).

Schema 2026.4 (shipped with 2026.4.3)

Renamed DeepSoilTemperature to AnnualMeanAirTemperature (#1240); removed MinimumVolumeOfDHWinUse and MaximumVolumeOfDHWinUse (#1242); split STEBBS HeatingSetpointTemperature and CoolingSetpointTemperature into scalar + *Profile siblings gated on model.physics.setpointmethod (#1261); added daylight-control and lighting/metabolism fields.

Schema 2026.1 (shipped with 2026.1.28)

STEBBS clean-up (#879): Wallx1/Roofx1 replaced with WallOuterCapFrac/RoofOuterCapFrac; IndoorAirStartTemperature/OutdoorAirStartTemperature renamed to InitialIndoorTemperature/InitialOutdoorTemperature; DHWVesselEmissivity and runtime-state view-factor fields dropped. STEBBS hourly profiles added for setpoints, appliance, occupants and hot water (#1038). DeepSoilTemperature and DHW volume bounds still present.

Schema 2025.12 (shipped with 2025.10.15 and 2025.11.20)

Initial formal YAML schema. Pre-#879 STEBBS layout: Wallx1 / Roofx1 wall/roof compositions, DHWVesselEmissivity, standalone appliance/occupant fields, explicit initial-state and runtime-state slots.

For developer-side guidance on when a bump is required and which docs must move with it, see Schema Development Documentation and the .claude/rules/python/schema-versioning.md rule shipped with the repository.

Versioning Best Practices#

  1. Pin schema_version in shared configurations so the target shape is explicit.

  2. Upgrade via ``suews schema migrate`` rather than hand-editing; the tool preserves user-supplied values through rename chains and logs dropped fields so you can recover intent.

  3. Re-validate after migration: suews validate new_config.yml catches any downstream field that tightened at the same time.

  4. Quote the SUEWS release when sharing a config — the release tag anchors the schema label via _PACKAGE_TO_SCHEMA even if the reader has not internalised the CalVer policy.

FAQ#

Q: Do I need to add ``schema_version`` to my configs?

It is optional; if absent, SUEWS assumes the current version. For anything you intend to keep or share, add it.

Q: How often do schema versions change?

At most once per SUEWS release, and usually less often — 2025.10.15 and 2025.11.20 share schema 2025.12 because no breaking changes landed between them.

Q: What if I pin a schema that this SUEWS does not know about?

If the label is older and a migration handler is registered, the configuration loads transparently. If the label is newer (you are running an old SUEWS against a new YAML) or older with no handler, you get a warning and may need to upgrade SUEWS or regenerate the YAML.

Q: Is this the same as the SUEWS model version?

No. The schema version tracks the YAML shape. The model version tracks the SUEWS code. One schema typically spans several model releases.