microsoft/semantic-kernel · error · FunctionExecutionException

This instance is frozen and cannot be modified.

Error message

This instance is frozen and cannot be modified.

What it means

`RestApiPayloadProperty._throw_if_frozen` raises `FunctionExecutionException` when a setter runs after `freeze()` marked the property (and its nested `_properties`) as immutable. The nested `for prop in self._properties: prop.freeze()` means an arbitrarily deep property tree is frozen top-down when the owning operation is frozen.

Source

Thrown at python/semantic_kernel/connectors/openapi_plugin/models/rest_api_payload_property.py:42

        self._name = name
        self._type = type
        self._properties = properties or []
        self._description = description
        self._is_required = is_required
        self._default_value = default_value
        self._schema = schema
        self._is_frozen = False

    def freeze(self):
        """Make the instance immutable, and freeze nested properties."""
        self._is_frozen = True
        for prop in self._properties:
            prop.freeze()

    def _throw_if_frozen(self):
        """Raise an exception if the object is frozen."""
        if self._is_frozen:
            raise FunctionExecutionException("This instance is frozen and cannot be modified.")

    @property
    def name(self):
        """Get the name of the property."""
        return self._name

    @name.setter
    def name(self, value: str):
        self._throw_if_frozen()
        self._name = value

    @property
    def type(self):
        """Get the type of the property."""
        return self._type

    @type.setter
    def type(self, value: str):

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Edit the underlying OpenAPI spec and re-parse to get fresh, unfrozen properties.
  2. Build a replacement `RestApiPayloadProperty(...)` and swap it in before `freeze()` runs.
  3. Treat parsed operations as read-only after registration; do all transformation on the raw spec dict.
  4. If you must reuse metadata, deep-copy the operation tree before any mutation.

Example fix

// before
prop = operation.payload.properties[0]
prop.name = "renamed"  # raises 1482

// after
import copy
fresh = copy.deepcopy(operation)  # before freeze, or re-parse the spec
fresh.payload.properties[0].name = "renamed"
Defensive patterns

Strategy: validation

Validate before calling

def assert_property_mutable(prop) -> None:
    if getattr(prop, "_is_frozen", False):
        raise RuntimeError(f"RestApiPayloadProperty '{prop.name}' is frozen.")

for p in operation.payload.properties:
    assert_property_mutable(p)

Type guard

def is_unfrozen_property(obj) -> bool:
    return hasattr(obj, "_is_frozen") and not obj._is_frozen

Try / catch

from semantic_kernel.exceptions import FunctionExecutionException

try:
    prop.name = renamed
except FunctionExecutionException as e:
    if "frozen" in str(e):
        prop = RestApiPayloadProperty(name=renamed, type=prop.type)
    else:
        raise

Prevention

When it happens

Trigger: Setting `name`, `type`, `description`, etc. on a payload property that lives under a payload/property whose owning operation has already been frozen. The freeze originates from `RestApiPayload.freeze()` which originates from `RestApiOperation.freeze()` during registration.

Common situations: Walking `operation.payload.properties` and renaming/retyping entries after the kernel function already exists; caching a parsed operation and mutating it for a second plugin; test fixtures that post-edit parsed trees.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/62490788de43b385. Report an issue: GitHub.