canopy-network/canopy · error · PluginError

1

1

Error message

Contract fsm_id is not set

What it means

Raised in state_read when the Contract object passed in has no fsm_id assigned. The FSM routes plugin messages by fsm_id, so a request without one cannot be correlated to a contract and would be rejected or misrouted.

Source

Thrown at plugin/python/contract/plugin.py:186

    async def _handshake(self) -> None:
        """Handshake sends the contract configuration to the FSM and awaits a reply."""
        logger.info("Handshaking with FSM")

        # Send config to FSM
        message = PluginToFSM()
        message.id = 0
        message.config.CopyFrom(self.plugin_config)

        await self._send_proto_msg(message)

        # Wait for response - the FSM will send back its config
        # This will be handled in _listen_for_inbound

    async def state_read(self, contract: Contract, request: PluginStateReadRequest) -> PluginStateReadResponse:
        """StateRead sends a state read request to FSM and waits for response."""
        if contract.fsm_id is None:
            raise PluginError(1, "plugin", "Contract fsm_id is not set")

        fsm_id = contract.fsm_id

        # Create future for response
        future: asyncio.Future = asyncio.Future()
        self._pending[fsm_id] = future
        self._request_contracts[fsm_id] = contract

        # Send request
        message = PluginToFSM()
        message.id = fsm_id
        message.state_read.CopyFrom(request)

        try:
            logger.debug(f"0x{fsm_id:x}: state_read")
            await self._send_proto_msg(message)

            # Wait for response with timeout

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Ensure the contract is registered with the FSM (handshake/registration assigns fsm_id) before calling state_read.
  2. Do not construct ad-hoc Contract objects for state reads; pass the FSM-created contract instance.
  3. Check that deserialization/creation code that builds Contract objects populates fsm_id.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at plugin/python/contract/plugin.py:186 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/1721aa556e95a6cb. Report an issue: GitHub.