reflex-dev/reflex · error · ValueError

app_id should be a string

Error message

app_id should be a string

What it means

Raised by get_app() when app_id is not a non-empty string. The function validates its input before hitting GET /api/v1/apps/{app_id}, because an invalid id would either produce a meaningless URL or an unhelpful 404/422 from the server. Common causes: passing the app dict instead of its 'id' key, an int id, or None.

Source

Thrown at packages/reflex-hosting-cli/src/reflex_cli/utils/hosting.py:912

    Args:
        app_id: The ID of the application to retrieve.
        client: The authenticated client

    Returns:
        dict: The application details as a dictionary.

    Raises:
        NotAuthenticatedError: If the token is not valid.
        GetAppError: If the request to get the app fails.
        ValueError: If the app_id is not valid.

    """
    import httpx

    if not isinstance(client, AuthenticatedClient):
        raise NotAuthenticatedError("not authenticated")
    if not isinstance(app_id, str) or not app_id:
        raise ValueError("app_id should be a string")
    response = httpx.get(
        urljoin(constants.Hosting.HOSTING_SERVICE, f"/api/v1/apps/{app_id}"),
        headers=authorization_header(client.token),
        timeout=constants.Hosting.TIMEOUT,
    )
    try:
        response.raise_for_status()
    except httpx.HTTPStatusError as ex:
        try:
            raise GetAppError(ex.response.json().get("detail")) from ex
        except json.JSONDecodeError:
            raise GetAppError(ex.response.text) from ex
    return response.json()


def create_app(
    app_name: str,
    client: AuthenticatedClient,

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Pass the app's id string: get_app(client, app_id=app['id']) or str(app_id)
  2. If the id comes from user input or another API, check it is a non-empty str before calling
  3. For UUID objects, convert with str() first

Example fix

# before
app = get_app(client, app_id=app_json)  # dict passed

# after
app = get_app(client, app_id=app_json["id"])  # id string
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(app_id, str) or not app_id:
    raise ValueError(f"app_id must be a non-empty str, got {app_id!r}")
app = get_app(client, app_id)

Type guard

def is_valid_app_id(app_id: object) -> bool:
    return isinstance(app_id, str) and bool(app_id)

Try / catch

try:
    get_app(client, app_id)
except ValueError as ex:
    if "app_id" in str(ex):
        app_id = str(app["id"])
        get_app(client, app_id)
    else:
        raise

Prevention

When it happens

Trigger: Calling get_app() (or delete_app / get_app_logs) with app_id=None, an int, or "" — e.g. get_app(client, app) where app is the dict returned by create_app instead of app["id"].

Common situations: Forgetting to extract the 'id' field from an app object/dict; passing a UUID object instead of str(uuid); passing an empty variable from a failed lookup upstream.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/a6d571ca104dcf18. Report an issue: GitHub.