Version Checks (indicate both or one)
Issue Description
I'm running a simple example using PyPSA and it used to work on the previous version 0.35.2. On v1.0.0, it seems that the index in the define_operational_constraints_for_extendables (lhs_lower = dispatch - min_pu * capacity) is misnaming it to "dim_0" instead of "snapshot".
Reproducible Example
import pandas as pd
import pypsa
periods = [2025, 2030]
timestamps_2025 = pd.date_range("2025-08-11 00:00", periods=4, freq="H")
timestamps_2030 = pd.date_range("2030-08-11 00:00", periods=4, freq="H")
period_labels = [2025] * len(timestamps_2025) + [2030] * len(timestamps_2030)
timestamps = list(timestamps_2025) + list(timestamps_2030)
multi_snapshots = pd.MultiIndex.from_arrays(
[period_labels, timestamps], names=["period", "timestamp"]
)
network = pypsa.Network()
network.set_snapshots(multi_snapshots)
weightings = pd.Series(
[1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0], index=multi_snapshots, name="objective"
)
network.snapshot_weightings = weightings
network.snapshot_weightings["period"] = network.snapshots.get_level_values("period")
network.investment_periods = pd.Index([2025, 2030])
network.investment_period_weightings["discount_rate"] = 0.05
network.investment_period_weightings["objective"] = {2025: 1, 2030: 1}
network.investment_period_weightings["years"] = {2025: 5, 2030: 5}
if "period" in network.snapshot_weightings.columns:
network.snapshot_weightings = network.snapshot_weightings.drop(columns="period")
network.add("Bus", "bus0")
network.add("Carrier", "gas", co2_emissions=0.5) # tCO2 per MWh
network.add("Carrier", "wind", co2_emissions=0.0)
# Add fossil generator (with emissions)
network.add(
"Generator",
"gen0",
bus="bus0",
p_nom=100,
marginal_cost=10,
p_nom_extendable=True,
capital_cost=60,
carrier="gas",
)
# Add wind generator (no emissions)
network.add(
"Generator",
"wind0",
bus="bus0",
p_nom=80,
marginal_cost=0,
p_nom_extendable=True,
capital_cost=100,
carrier="wind",
)
load_series = pd.Series(120, index=network.snapshots)
network.add("Load", "load0", bus="bus0", p_set=load_series)
availability = pd.DataFrame(
{
"gen0": [1.0, 0.8, 0.5, 0.4] * 2,
"wind0": [0.4, 0.2, 0.3, 0.1] * 2,
},
index=network.snapshots,
)
network.generators_t.p_max_pu = availability
positive_snapshots = weightings[weightings > 0].index
network.set_snapshots(positive_snapshots)
network.snapshot_weightings = weightings.loc[positive_snapshots]
model = network.optimize.create_model(multi_investment_periods=True)
solve_status, solve_condition = network.optimize.solve_model(
assign_all_duals=True,
solver_name="highs",
)
Expected Behavior
Traceback (most recent call last):
File "C:\Users\mbui\Desktop\git\Snakemake_Minimal_Example\min_example.py", line 69, in
model = network.optimize.create_model(multi_investment_periods=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui\Desktop\github\PyPSA\pypsa\optimization\optimize.py", line 568, in create_model
define_operational_constraints_for_extendables(
File "C:\Users\mbui\Desktop\github\PyPSA\pypsa\optimization\constraints.py", line 185, in define_operational_constraints_for_extendables
lhs_lower = dispatch - min_pu * capacity
~~~~~~~~~^~~~~~~~~~~~~~~~~~~
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\variables.py", line 500, in sub
return self.to_linexpr() - other
~~~~~~~~~~~~~~~~~~^~~~~~~
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 1329, in sub
return self.add(-other)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 1301, in add
return merge([self, other], cls=self.class)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 2004, in merge
ds = xr.concat([d[["coeffs", "vars"]] for d in data], dim, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\concat.py", line 295, in concat
return _dataset_concat(
^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\concat.py", line 613, in _dataset_concat
align(
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 968, in align
aligner.align()
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 660, in align
self.align_indexes()
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 497, in align_indexes
update_dicts(key, joined_index, joined_index_vars, need_reindex)
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 419, in update_dicts
raise AlignmentError(
xarray.structure.alignment.AlignmentError: cannot align objects on coordinate 'period' because of conflicting indexes
first index: PandasIndex(MultiIndex([(2025, '2025-08-11 00:00:00'),
(2025, '2025-08-11 01:00:00'),
(2025, '2025-08-11 03:00:00'),
(2030, '2030-08-11 00:00:00'),
(2030, '2030-08-11 02:00:00'),
(2030, '2030-08-11 03:00:00')],
name='dim_0'))
second index: PandasIndex(MultiIndex([(2025, '2025-08-11 00:00:00'),
(2025, '2025-08-11 01:00:00'),
(2025, '2025-08-11 03:00:00'),
(2030, '2030-08-11 00:00:00'),
(2030, '2030-08-11 02:00:00'),
(2030, '2030-08-11 03:00:00')],
name='snapshot'))
first variable: <xarray.IndexVariable 'dim_0' (dim_0: 6)> Size: 48B
second variable: <xarray.IndexVariable 'snapshot' (snapshot: 6)> Size: 48B
[6 values with dtype=int64]
Installed Versions
Details
appdirs==1.4.4
argparse-dataclass==2.0.0
attrs==25.4.0
Bottleneck==1.6.0
cachetools==6.2.1
certifi==2025.10.5
cftime==1.6.5
charset-normalizer==3.4.3
click==8.3.0
cloudpickle==3.1.1
colorama==0.4.6
conda-inject==1.3.2
ConfigArgParse==1.7.1
connection_pool==0.0.3
contourpy==1.3.3
cycler==0.12.1
dask==2025.10.0
deprecation==2.1.0
docutils==0.22.2
dpath==2.2.0
fastjsonschema==2.21.2
fonttools==4.60.1
fsspec==2025.9.0
geopandas==1.1.1
gitdb==4.0.12
GitPython==3.1.45
google-api-core==2.26.0
google-auth==2.41.1
google-cloud-core==2.4.3
google-cloud-storage==3.4.1
google-crc32c==1.7.1
google-resumable-media==2.7.2
googleapis-common-protos==1.70.0
highspy==1.11.0
humanfriendly==10.0
idna==3.10
immutables==0.21
Jinja2==3.1.6
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
jupyter_core==5.8.1
kiwisolver==1.4.9
Levenshtein==0.27.1
linopy==0.5.7
locket==1.0.0
MarkupSafe==3.0.3
matplotlib==3.10.7
narwhals==2.8.0
nbformat==5.10.4
netCDF4==1.7.3
networkx==3.5
numexpr==2.14.1
numpy==2.3.4
packaging==25.0
pandas==2.3.3
partd==1.4.2
pillow==12.0.0
platformdirs==4.5.0
plotly==6.3.1
polars==1.34.0
polars-runtime-32==1.34.0
proto-plus==1.26.1
protobuf==6.33.0
psutil==7.1.0
PuLP==3.3.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pydeck==0.9.1
pyogrio==0.11.1
pyparsing==3.2.5
pyproj==3.7.2
pypsa==1.0.0
pyreadline3==3.5.4
python-dateutil==2.9.0.post0
pytz==2025.2
pywin32==311
PyYAML==6.0.3
RapidFuzz==3.14.1
referencing==0.36.2
requests==2.32.5
reretry==0.11.8
rpds-py==0.27.1
rsa==4.9.1
scipy==1.16.2
seaborn==0.13.2
shapely==2.0.7
six==1.17.0
smart_open==7.3.1
smmap==5.0.2
snakemake==9.12.0
snakemake-interface-common==1.22.0
snakemake-interface-executor-plugins==9.3.9
snakemake-interface-logger-plugins==2.0.0
snakemake-interface-report-plugins==1.2.0
snakemake-interface-scheduler-plugins==2.0.1
snakemake-interface-storage-plugins==4.2.3
tabulate==0.9.0
throttler==1.2.2
toolz==1.0.0
tqdm==4.67.1
traitlets==5.14.3
typing_extensions==4.15.0
tzdata==2025.2
urllib3==2.5.0
validators==0.35.0
wrapt==1.17.3
xarray==2025.9.0
yte==1.9.0
Version Checks (indicate both or one)
I have confirmed this bug exists on the lastest release of PyPSA.
I have confirmed this bug exists on the current
masterbranch of PyPSA.Issue Description
I'm running a simple example using PyPSA and it used to work on the previous version 0.35.2. On v1.0.0, it seems that the index in the define_operational_constraints_for_extendables (lhs_lower = dispatch - min_pu * capacity) is misnaming it to "dim_0" instead of "snapshot".
Reproducible Example
Expected Behavior
Traceback (most recent call last):
File "C:\Users\mbui\Desktop\git\Snakemake_Minimal_Example\min_example.py", line 69, in
model = network.optimize.create_model(multi_investment_periods=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui\Desktop\github\PyPSA\pypsa\optimization\optimize.py", line 568, in create_model
define_operational_constraints_for_extendables(
File "C:\Users\mbui\Desktop\github\PyPSA\pypsa\optimization\constraints.py", line 185, in define_operational_constraints_for_extendables
lhs_lower = dispatch - min_pu * capacity
~~~~~~~~~^~~~~~~~~~~~~~~~~~~
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\variables.py", line 500, in sub
return self.to_linexpr() - other
~~~~~~~~~~~~~~~~~~^~~~~~~
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 1329, in sub
return self.add(-other)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 1301, in add
return merge([self, other], cls=self.class)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\linopy\expressions.py", line 2004, in merge
ds = xr.concat([d[["coeffs", "vars"]] for d in data], dim, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\concat.py", line 295, in concat
return _dataset_concat(
^^^^^^^^^^^^^^^^
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\concat.py", line 613, in _dataset_concat
align(
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 968, in align
aligner.align()
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 660, in align
self.align_indexes()
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 497, in align_indexes
update_dicts(key, joined_index, joined_index_vars, need_reindex)
File "C:\Users\mbui.venv\snakemake_pypsa_p312\Lib\site-packages\xarray\structure\alignment.py", line 419, in update_dicts
raise AlignmentError(
xarray.structure.alignment.AlignmentError: cannot align objects on coordinate 'period' because of conflicting indexes
first index: PandasIndex(MultiIndex([(2025, '2025-08-11 00:00:00'),
(2025, '2025-08-11 01:00:00'),
(2025, '2025-08-11 03:00:00'),
(2030, '2030-08-11 00:00:00'),
(2030, '2030-08-11 02:00:00'),
(2030, '2030-08-11 03:00:00')],
name='dim_0'))
second index: PandasIndex(MultiIndex([(2025, '2025-08-11 00:00:00'),
(2025, '2025-08-11 01:00:00'),
(2025, '2025-08-11 03:00:00'),
(2030, '2030-08-11 00:00:00'),
(2030, '2030-08-11 02:00:00'),
(2030, '2030-08-11 03:00:00')],
name='snapshot'))
first variable: <xarray.IndexVariable 'dim_0' (dim_0: 6)> Size: 48B
second variable: <xarray.IndexVariable 'snapshot' (snapshot: 6)> Size: 48B
[6 values with dtype=int64]
Installed Versions
Details
appdirs==1.4.4 argparse-dataclass==2.0.0 attrs==25.4.0 Bottleneck==1.6.0 cachetools==6.2.1 certifi==2025.10.5 cftime==1.6.5 charset-normalizer==3.4.3 click==8.3.0 cloudpickle==3.1.1 colorama==0.4.6 conda-inject==1.3.2 ConfigArgParse==1.7.1 connection_pool==0.0.3 contourpy==1.3.3 cycler==0.12.1 dask==2025.10.0 deprecation==2.1.0 docutils==0.22.2 dpath==2.2.0 fastjsonschema==2.21.2 fonttools==4.60.1 fsspec==2025.9.0 geopandas==1.1.1 gitdb==4.0.12 GitPython==3.1.45 google-api-core==2.26.0 google-auth==2.41.1 google-cloud-core==2.4.3 google-cloud-storage==3.4.1 google-crc32c==1.7.1 google-resumable-media==2.7.2 googleapis-common-protos==1.70.0 highspy==1.11.0 humanfriendly==10.0 idna==3.10 immutables==0.21 Jinja2==3.1.6 jsonschema==4.25.1 jsonschema-specifications==2025.9.1 jupyter_core==5.8.1 kiwisolver==1.4.9 Levenshtein==0.27.1 linopy==0.5.7 locket==1.0.0 MarkupSafe==3.0.3 matplotlib==3.10.7 narwhals==2.8.0 nbformat==5.10.4 netCDF4==1.7.3 networkx==3.5 numexpr==2.14.1 numpy==2.3.4 packaging==25.0 pandas==2.3.3 partd==1.4.2 pillow==12.0.0 platformdirs==4.5.0 plotly==6.3.1 polars==1.34.0 polars-runtime-32==1.34.0 proto-plus==1.26.1 protobuf==6.33.0 psutil==7.1.0 PuLP==3.3.0 pyasn1==0.6.1 pyasn1_modules==0.4.2 pydeck==0.9.1 pyogrio==0.11.1 pyparsing==3.2.5 pyproj==3.7.2 pypsa==1.0.0 pyreadline3==3.5.4 python-dateutil==2.9.0.post0 pytz==2025.2 pywin32==311 PyYAML==6.0.3 RapidFuzz==3.14.1 referencing==0.36.2 requests==2.32.5 reretry==0.11.8 rpds-py==0.27.1 rsa==4.9.1 scipy==1.16.2 seaborn==0.13.2 shapely==2.0.7 six==1.17.0 smart_open==7.3.1 smmap==5.0.2 snakemake==9.12.0 snakemake-interface-common==1.22.0 snakemake-interface-executor-plugins==9.3.9 snakemake-interface-logger-plugins==2.0.0 snakemake-interface-report-plugins==1.2.0 snakemake-interface-scheduler-plugins==2.0.1 snakemake-interface-storage-plugins==4.2.3 tabulate==0.9.0 throttler==1.2.2 toolz==1.0.0 tqdm==4.67.1 traitlets==5.14.3 typing_extensions==4.15.0 tzdata==2025.2 urllib3==2.5.0 validators==0.35.0 wrapt==1.17.3 xarray==2025.9.0 yte==1.9.0