> ## Documentation Index
> Fetch the complete documentation index at: https://docs.relayintelligence.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> What each error means and how to fix it.

When the server can't serve an observation, `infer` returns an error instead of raising, and the connection stays open:

```python theme={null}
result = policy.infer(obs)
if isinstance(result, dict) and result.get("type") == "error":
    print(result["message"])
```

## Errors from the server

<AccordionGroup>
  <Accordion title="Internal inference error">
    The model couldn't run on this observation. For security, the server doesn't send internal details. Almost always the observation doesn't match what the model expects:

    * **Wrong state length.** π0.5 needs exactly 32 values, shaped `(32,)` or `(1, 32)`.
    * **No cameras.** π0 and π0.5 need at least one of the three camera keys. Check that the key names are spelled exactly as listed.
    * **Wrong image layout.** Frames must be height × width × 3 RGB `uint8`, or floats in `[0, 1]`. Channel-first `(3, H, W)` arrays, grayscale frames and floats in `[0, 255]` are rejected.
    * **NaN or Inf** in the state or a float image.
    * **GR00T structure.** `video` and `state` must be dicts with the shapes on the GR00T tab of [Observations](/observations), and frames must be raw arrays, not JPEG bytes.

    Compare your observation with the example for your model on the [Observations](/observations) page, and check `policy.get_server_metadata()`.
  </Accordion>

  <Accordion title="Invalid request payload">
    The server couldn't decode the message. Usually a value can't be serialized: an object, structured or complex array, or the observation isn't a dict. Use plain numbers, strings, bytes, lists, dicts and numeric NumPy arrays only.

    Observations over 64 MiB also produce this error. Send fewer or smaller frames, or JPEG bytes.
  </Accordion>

  <Accordion title="Unknown LoRA adapter 'x'; this server serves [...]">
    `sampling_params.lora` names an adapter that isn't registered on this server. The message lists the adapters you can use. An empty list means the server serves only the base model, so remove the `lora` key or set it to `false`.
  </Accordion>

  <Accordion title="lora scale must be a number">
    In `{"name": ..., "scale": ...}`, `scale` must be a finite number.
  </Accordion>
</AccordionGroup>

## Connection problems

<AccordionGroup>
  <Accordion title="KeyError: 'WALLE_URL'">
    `WALLE_URL` isn't set. Export it, or put it in a `.env` file in the directory you run from. See [Quickstart](/quickstart).
  </Accordion>

  <Accordion title="PolicyClient(...) hangs on connect">
    The server is probably loading its model after a deploy or a scale-up. The first connection waits for it, which can take a few minutes, then later connections are fast.

    If it never connects, check that `WALLE_URL` has the right workspace, keeps the `{model}` placeholder and, for a development server, has `-dev` before `.modal.run`.
  </Accordion>

  <Accordion title="InvalidStatus: server rejected WebSocket connection: HTTP 404">
    No server is deployed for that model ID in that workspace. Check the model ID (`pi05`, `pi0` or `groot`) and the workspace in `WALLE_URL`.
  </Accordion>

  <Accordion title="ConnectionClosed in the middle of a run">
    The server closes connections that are idle for 30 seconds, and networks drop. Create a new `PolicyClient` and resend the observation. See [Connection lifetime](/control-loop#connection-lifetime) for a reconnect pattern.
  </Accordion>

  <Accordion title="Calls are slower than expected">
    Check that the client took the direct route: `"direct_url" in policy.get_server_metadata()` should be `True`, and `WALLE_DIRECT` should be unset or `1`. Then run `python examples/demo.py` to separate network time from inference time. See [Latency](/control-loop#latency).
  </Accordion>
</AccordionGroup>

## Actions look wrong

<AccordionGroup>
  <Accordion title="The robot moves, but not toward the task">
    * Check that each camera key points at the right physical camera. Swapping the wrist and base cameras confuses the model without causing an error.
    * Check that the state is in the joint order and units the checkpoint was trained on.
    * The base checkpoints are generalists. For reliable behavior on a specific robot, use an adapter fine-tuned on that robot's data.
  </Accordion>

  <Accordion title="Results differ between identical runs">
    Sampling is random by default. Add `"seed": 0` (any integer) to get the same actions for the same observation.
  </Accordion>

  <Accordion title="Motion is jerky at chunk boundaries">
    Execute more of each chunk before replanning, or request the next chunk early so it's ready when the current one ends. See [Choosing how much of a chunk to execute](/control-loop#choosing-how-much-of-a-chunk-to-execute).
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.