Skip to content

Introspection tools hide deprecated schema members, so absent and deprecated look identical #686

Description

@adriannoes

Problem

  • The introspection tools silently hide every deprecated schema member. introspect_type,
    introspect_mutation, introspect_query and search_schema never pass includeDeprecated: true, so
    GraphQL returns only non-deprecated fields, input fields and enum values.
  • A caller reads the result as the complete shape and concludes a field does not exist when it does.
    Deprecated is not the same as absent: a deprecated input field is still writable, and a deprecated output
    field is still selectable and may still be what our own queries select.
  • The failure is silent in the worst way. Nothing in the response says members were withheld, so nothing
    prompts a second look.

Evidence

  • packages/sdk/src/pipefy_sdk/queries/introspection_queries.py: the type document selects inputFields
    (line 24) and enumValues (line 36) with no arguments. The field selections used by the mutation and
    query documents have the same shape.
  • Verified on 2026-09-15 against UpdatePipeInput:
    • Through introspect_type: 15 input fields.
    • Through a raw __type(name: "UpdatePipeInput") { inputFields(includeDeprecated: true) }: 16.
    • The hidden one is anyone_can_create_card, deprecated with the reason that form permissions should be
      used instead. The mutation accepts it today.
  • This already produced a wrong issue body. Pipes: description is not writable, and anyone_can_create_card is writable only through a deprecated input (API-bound) #622 asserted that anyone_can_create_card is readable and not
    writable. It is writable and deprecated. The claim was built on a tool result that withheld the field.
  • A second instance on the output side: FieldConditionAction.phaseFieldId is deprecated in favour of
    phaseField, and introspect_type("FieldConditionAction") does not show it. Two of our own read queries
    select that deprecated field (packages/sdk/src/pipefy_sdk/queries/pipe_config_queries.py:209 and
    :233), so the tool cannot surface a deprecation our own code depends on.
  • Scope of the doubt: any "absent from the schema" conclusion reached through these tools is unsound until
    re-checked. Enum values are affected too, which matters for the action and event catalogs.

Scope

  • Add includeDeprecated: true to fields, inputFields and enumValues in
    packages/sdk/src/pipefy_sdk/queries/introspection_queries.py.
  • Return isDeprecated and deprecationReason per member, and keep them through the formatter so a caller
    can tell a live member from a retired one.
  • Decide the default presentation. Including deprecated members and marking them is the honest default for
    an agent deciding whether a write is possible. If a compact default is preferred instead, add an explicit
    flag and state in the docstring that the default hides members.
  • Update the introspection skill to say that a member missing from a result may be deprecated rather than
    absent, until the marker ships.

Acceptance

  • introspect_type("UpdatePipeInput") returns 16 input fields and marks anyone_can_create_card
    deprecated with its reason.
  • introspect_type("FieldConditionAction") shows phaseFieldId with its deprecation reason.
  • Deprecated enum values appear and are marked, verified against one enum that has them.
  • Unit tests pin the document shape so a later edit cannot drop the argument silently.
  • Parity across SDK, MCP and CLI.

Notes

Activity

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

Metadata

Metadata

Assignees

Labels

bugDefect: incorrect or broken behavior vs documented contractreliabilityCorrectness under failure: retries, idempotency, false errors, resilience

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions