Skip to content

specifiedByURL field on __Type is declared in the schema but not handled by the resolver #629

Description

@imor

Summary

The introspection field __Type.specifiedByURL is declared in pg_graphql's schema definition, but querying it errors with "unexpected field specifiedByURL type on __Type". The schema advertises a field that the resolver cannot resolve.

Reproduction

create extension if not exists pg_graphql;
comment on schema public is e'@graphql({"introspection": true})';

select graphql.resolve($$
  { __type(name: "String") { name specifiedByURL } }
$$);

Result:

{
  "data": null,
  "errors": [
    { "message": "unexpected field specifiedByURL type on __Type" }
  ]
}

The same error occurs for any type name (Blog, __Type, String, etc.), since the failure is in the __Type field dispatch and never reaches type-specific logic.

Root cause

specifiedByURL is declared as a field on __Type in src/graphql.rs:2922-2929:

__Field {
    type_: __Type::Scalar(Scalar::String(None)),
    name_: "specifiedByURL".to_string(),
    args: vec![],
    description: None,
    deprecation_reason: None,
    sql_type: None,
}

But the __Type field resolver in src/builder.rs has match arms only for name, description, kind, fields, inputFields, interfaces, enumValues, possibleTypes, ofType, and __typename. Anything else falls into the catch-all at src/builder.rs:3006-3011:

_ => {
    return Err(GraphQLError::internal(format!(
        "unexpected field {} type on __Type",
        type_field_name
    )));
}

Impact

Standard GraphQL clients (graphql-js, Apollo, Relay) include specifiedByURL in their introspection queries since it became part of the spec (October 2021). Any client using a stock introspection query against a pg_graphql instance with introspection enabled will receive an error and fail to load the schema.

Spec reference

Per the GraphQL spec and the @specifiedBy RFC, specifiedByURL: String should:

Return the URL specified via @specifiedBy for custom scalar types.
Return null for all other types (objects, interfaces, unions, enums, input objects, lists, non-null wrappers, and built-in scalars).

Suggested fix

Add a specifiedByURL arm to the __Type field match in src/builder.rs that returns null for all types. pg_graphql does not currently support @specifiedBy, so a constant null resolver matches behavior and unblocks standard clients:

"specifiedByURL" => __TypeField::SpecifiedByURL(None),

(plus the corresponding __TypeField variant and serializer). If/when @specifiedBy is added to pg_graphql, this can be wired up to return the actual URL for custom scalars.

Test coverage

test/sql/introspection.sql currently omits specifiedByURL from the __Type field-coverage test with a comment explaining why. That omission can be removed once this is fixed.

Activity

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

Metadata

Metadata

Assignees

Labels

triage-requiredPending triage from maintainers

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions