Skip to content

astro deployment pool copy fails on default_pool (missing update_mask) #1909

@bmanan7

Description

@bmanan7

Describe the bug

When running astro deployment pool copy, the command fails when copying the default_pool from one deployment to another. The CLI attempts to update the existing default_pool in the target deployment and receives a 400 response from the Airflow API:

astro deployment pool copy --source-id cmXXXXXX --target-id cmeXXXXXXX

Copying Pool default_pool
Error: API error (400): {"detail":"Only slots and included_deferred can be modified on Default Pool"}

I also tried calling the Airflow API directly via curl to confirm, and the same error is returned when updating the default pool:

curl -X PATCH \
  "https://$AIRFLOW_URL/api/v2/pools/default_pool" \
  -H "Authorization: Bearer $AIRFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"slots":64,"description":"Default pool","include_deferred":false}'
# response:
{"detail":"Only slots and included_deferred can be modified on Default Pool"} 

Looking at the astro‑cli implementation, the CopyPool function iterates through all pools and calls airflowAPIClient.UpdatePool() whenever a pool with the same name already exists in the target deployment. It passes the whole pool object, including fields like Description and Name

If the pool is not there it will create it:

err = airflowAPIClient.CreatePool(toAirflowURL, fromPoolResp.Pools[i])

This problem occurs when the pool is already there. So, in all the deployment we will always have default_pool as the user is not allowed to delete it from the UI. Everytime this command will fail with 400 error code as the core airflow code expects update_mask field to be present with allowed values(slots and include_deferred) only: https://github.com/astronomer/airflow/blob/3cb49c7c9a645add7d083564f8099f7059773b22/airflow-core/src/airflow/api_fastapi/core_api/routes/public/pools.py#L155

In Airflow API, as we can see the PATCH handler for pools explicitly prohibits changing the name or description of default_pool and requires an update_mask that only includes slots and include_deferred. Because the CLI does not handle this special case and does not set an update_mask, the API rejects the request.

What CLI Version did you experience this bug?

astro version
Astro CLI Version: 1.35.1

This CLI bug is related to which Astronomer Platform?

  • Astro
  • Software
  • None/Unknown

What Operating System is the above CLI installed on?

🪜 Steps To Reproduce

  • Ensure you have two Astro deployments and that both deployments contain the default Airflow pool (default_pool).
  • Run the CLI command to copy pools from one deployment to another:
astro deployment pool copy --source-id <source-deployment-id> --target-id <target-deployment-id>
  • Observe that it successfully creates any non‑existent pools but fails on the default_pool, printing an error similar to:
Copying Pool default_pool
Error: API error (400): {"detail":"Only slots and included_deferred can be modified on Default Pool"}
  • Optionally, reproduce via direct API call as shown above with curl; the response confirms that only slots and include_deferred can be modified.

Additional Context

The Airflow API’s PATCH endpoint for pools explicitly checks if the pool name is default_pool and only allows updating the slots and include_deferred fields when an update_mask specifying those fields is provided

patch_pool

The astro‑cli’s CopyPool function does not account for this and always passes the full pool object for updates. As a result, the default pool cannot be copied or updated using the current CLI command. A potential fix would be to detect when the pool name is default_pool and set an update_mask of [ "slots", "include_deferred" ], and only include those fields in the patch request, or skip copying default_pool entirely if not needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions