Skip to content

ComposioConnectionsResponse::Object silently yields zero connections on an unrecognized object shape #17

Description

@senamakel

What

ComposioConnectionsResponse is an untagged enum with a #[serde(default)] on the object variant's connections field:

#[serde(untagged)]
pub enum ComposioConnectionsResponse {
    List(Vec<ComposioConnection>),
    Object {
        #[serde(default)]
        connections: Vec<ComposioConnection>,
    },
}

Untagged matching tries List first; any JSON object fails that and falls through to Object, where the default means a missing connections key deserializes to an empty vector instead of erroring. So if the backend ever renames the key or changes the wrapper shape, list_composio_connections returns Ok with zero connections rather than failing — a wire-format change reads to callers as "this user has no integrations connected."

Raised by CodeRabbit on #16 (#16 (comment)). Filed separately because #16 is a verified pure file move and fixing it there would have broken that guarantee.

What is not affected

The related scenario CodeRabbit raised — an error-shaped object returned with HTTP 200 — is already handled upstream of deserialization. unwrap_envelope in src/lib.rs turns {success: false, ...} into Error::Envelope before any typed decoding runs, so that path already fails loudly.

The exposure is narrower: a successful envelope whose data object doesn't carry connections.

Suggested fix

Drop the #[serde(default)] so the object variant requires the key:

Object { connections: Vec<ComposioConnection> },

A shape the SDK doesn't recognize then fails as a decode error, which is the honest outcome.

Worth confirming against the deployed backend first that no live response relies on the object variant with connections absent — the doc comment notes the backend has emitted both a bare array and { connections: [...] }, and the default may have been added to paper over a third shape observed in the wild. If so, that third shape should get its own variant rather than being silently flattened to empty.

Acceptance

  • The object variant requires connections.
  • A round-trip test covers the bare-array shape, the {connections: [...]} shape, and an unrecognized object shape erroring rather than returning empty.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: p3Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions