Skip to content

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

@imor

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.

Metadata

Metadata

Assignees

Labels

triage-requiredPending triage from maintainers

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions