Skip to content

fix: preserve composed directives with executable locations in supergraph#297

Open
adambenhassen wants to merge 5 commits intomainfrom
directives-fix
Open

fix: preserve composed directives with executable locations in supergraph#297
adambenhassen wants to merge 5 commits intomainfrom
directives-fix

Conversation

@adambenhassen
Copy link
Copy Markdown

@adambenhassen adambenhassen commented Apr 10, 2026

Summary

@composeDirective was not preserving directive definitions in the supergraph when the directive only had executable locations (QUERY, MUTATION, FIELD, VARIABLE_DEFINITION). Directives with schema-level locations (OBJECT, FIELD_DEFINITION) worked correctly.

This affected users trying to use @composeDirective to promote operation-level directives (e.g. @mcpTool, @mcpDescription) into the supergraph for app deployment validation.

Root cause

The build() function strips executable directives that aren't shared across all subgraphs. There was already a carve-out for composed directives at the location-filtering level, but it only protected schema-level locations. Composed directives with purely executable locations still entered the stripping loop and were deleted because they failed the cross-subgraph identity check.

Proposed fix

Skip the entire executable directive stripping block for composed directives. If a directive is marked via @composeDirective, the user explicitly requested it in the supergraph, the composition should not strip it.

Tests added

  • Non-composed executable directive with QUERY | MUTATION is still omitted when only one subgraph defines it
  • Composed directive with only executable locations (QUERY | MUTATION) is preserved in supergraph
  • Composed directive with VARIABLE_DEFINITION | FIELD locations is preserved in supergraph
  • Composed directive with mixed schema and executable locations (FIELD | FIELD_DEFINITION) is preserved when only one subgraph defines it
  • Composed directive with only executable locations is preserved when both subgraphs define it
  • Conflicting composed directive definitions across subgraphs (documents Apollo behavioral difference)
  • Conflicting composed directive definitions with swapped types (proves Apollo resolves by service name order)

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request ensures that composed directives are preserved in the supergraph SDL, even when they contain executable locations and are defined in only one subgraph. The logic in src/supergraph/state.ts was updated to prevent stripping directives marked as composed. Additionally, new test cases were added to verify this behavior for various directive locations, including executable and mixed locations. I have no feedback to provide as there were no review comments to evaluate.

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@theguild/federation-composition 0.22.3-alpha-20260413175407-47a5f9a978af84306748fc0fc8cef3952339b995 npm ↗︎ unpkg ↗︎

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant