Skip to content

Prevent setting generate_template: true on generics#8379

Open
gmazoyer wants to merge 10 commits intorelease-1.8from
gma-20260213-8371
Open

Prevent setting generate_template: true on generics#8379
gmazoyer wants to merge 10 commits intorelease-1.8from
gma-20260213-8371

Conversation

@gmazoyer
Copy link
Contributor

@gmazoyer gmazoyer commented Feb 13, 2026

Why

Setting generate_template: true on a GenericSchema creates an invalid GraphQL schema, which breaks the frontend and prevents any GraphQL queries or mutations from running. This PR removes the generate_template attribute from GenericSchema so that it cannot be set anymore.

Important

We should probably backport this to stable too.

Closes #8371

What changed

  • Schema load will now be rejected if a user tries to set generate_template on a generic since the attribute no longer exists
  • Removed the integration test TestSchemaTemplateGenericInheritance that exercised the now-blocked scenario
  • Adapted some component tests to avoid impossible code path

Auto-generated sub-templates for generics used as component peers (e.g. InfraInterface generic referenced via a component relationship) are not affected, that path relies already supported generics without requiring them to have generate_template set to true.

How to review

Small diff. Focus on the validation method in schema_branch.py but it's mostly about adding isinstance(node, ...) for typing reasons and conditionals. There is also a migration to remove the attribute from the graph.

How to test

# Run migration test
uv run pytest backend/tests/component/core/migrations/graph/test_062_remove_generic_generate_template.py -v

# Existing sub-template tests still pass (DEVICE + INTERFACE_HOLDER path)
uv run pytest backend/tests/component/core/schema_manager/test_manager_schema.py \
  -k "test_manage_object_templates_with_component_relationships or test_identify_object_templates_with_generics" -v

Impact & rollout

  • Backward compatibility: users with generate_template: true on a generic will get an error on next schema load but there should not be running instances out there using this, as they would be broken anyway.
  • Deployment notes: safe to deploy independently

Checklist

Summary by CodeRabbit

  • Bug Fixes

    • Removed the generate_template option from Generic schema definitions to prevent invalid GraphQL schemas and related frontend/backend errors
  • Migrations

    • Added a migration to remove legacy generate_template attributes and clean up related schema entries
  • Documentation

    • Clarified docs: generate_template is only available on node definitions
  • UI

    • "Generate template" setting now appears only for node schemas
  • Chores

    • Bumped internal graph version and updated tests to reflect changes

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

GRAPH_VERSION bumped to 62 and a new migration (Migration062) added to delete generate_template attributes from SchemaGeneric instances and their SchemaAttribute definitions. The generate_template attribute was removed from internal schema definitions and from public API/OpenAPI/types. Schema branch logic and frontend schema viewer were narrowed to operate on Node schemas for template generation. Documentation and examples were updated to indicate generate_template applies only to nodes. Tests were added for the migration, existing schema tests were renamed/expanded, and one integration test suite concerning generic-template inheritance was removed.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: preventing setting generate_template: true on generics. It accurately reflects the primary objective of the PR.
Description check ✅ Passed The description comprehensively covers all key sections: Why (problem and goal), What changed (behavioral and implementation details), How to review, How to test, Impact & rollout, and checklist items completed.
Linked Issues check ✅ Passed The PR directly addresses issue #8371 by removing the generate_template attribute from GenericSchema to prevent invalid GraphQL schema generation. All code changes align with the stated objective of blocking generate_template on generics.
Out of Scope Changes check ✅ Passed All changes are directly scoped to removing generate_template from GenericSchema and related updates. No unrelated modifications detected; test adaptations and documentation changes are necessary consequences of the primary change.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the group/backend Issue related to the backend (API Server, Git Agent) label Feb 13, 2026
@github-actions github-actions bot added the type/documentation Improvements or additions to documentation label Feb 13, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 13, 2026

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing gma-20260213-8371 (e1ff1c9) with release-1.8 (f2a87b9)1

Open in CodSpeed

Footnotes

  1. No successful run was found on release-1.8 (7f2ab39) during the generation of this report, so f2a87b9 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@ogenstad
Copy link
Contributor

Is this attribute ever set to True within the backend code when processing the schema? If not it might make more sense to remove the attribute? Alternatively convert it to a private attribute. One thing that I'd wonder with the current change is if we might have a situation if a user has set this to True and we'd prevent that schema from loading after an upgrade.

@ogenstad
Copy link
Contributor

FYI, this should target the release-1.8 branch.

@github-actions github-actions bot added the group/frontend Issue related to the frontend (React) label Feb 14, 2026
@gmazoyer gmazoyer changed the base branch from develop to release-1.8 February 14, 2026 14:16
@github-actions github-actions bot removed the group/frontend Issue related to the frontend (React) label Feb 16, 2026
@github-actions github-actions bot added the group/frontend Issue related to the frontend (React) label Feb 16, 2026
@gmazoyer gmazoyer force-pushed the gma-20260213-8371 branch 3 times, most recently from 09c52c5 to 91bfe79 Compare February 16, 2026 13:56
self.add_to_query(query)


class Migration062(GraphMigration):
Copy link
Contributor Author

@gmazoyer gmazoyer Feb 17, 2026

Choose a reason for hiding this comment

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

Not sure if this migration is too brutal. I expected that I needed to use NodeAttributeRemoveMigration but that was unsuccessful when running infrahub upgrade.

@gmazoyer gmazoyer marked this pull request as ready for review February 17, 2026 10:06
@gmazoyer gmazoyer requested review from a team as code owners February 17, 2026 10:06
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py (1)

60-69: validate_migration is a no-op — consider adding a pre-check.

The validate_migration method returns an empty MigrationResult without checking the graph state. This is acceptable since the queries are idempotent, but a pre-check verifying whether the migration is needed (e.g., checking if generate_template attributes exist on SchemaGeneric nodes) could provide better operational visibility.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py`
around lines 60 - 69, Migration062.validate_migration is currently a no-op; add
a pre-check that queries the graph (via the provided db/InfrahubDatabase) for
SchemaGeneric nodes that still have the generate_template attribute and use that
to populate and return a meaningful MigrationResult (e.g., mark as not_needed
when none found or include a warning/info when some exist) before running
RemoveGenericGenerateTemplateQuery and
RemoveGenericGenerateTemplateSchemaAttributeQuery; reference Migration062,
validate_migration, MigrationResult, RemoveGenericGenerateTemplateQuery,
RemoveGenericGenerateTemplateSchemaAttributeQuery, and the
SchemaGeneric·generate_template attribute when implementing the check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py`:
- Around line 29-57: The DETACH DELETE in
RemoveGenericGenerateTemplateSchemaAttributeQuery.query_init currently removes
sa and rel but leaves child Attribute and AttributeValue nodes orphaned; update
the Cypher to explicitly MATCH the child Attribute nodes (e.g., via
sa-[:HAS_ATTRIBUTE]->(attr:Attribute)) and their value nodes
(attr-[:HAS_VALUE]->(val)) with the same active relationship filters, collect
them (attr and val) and include them in the DETACH DELETE so you remove sa, rel,
attr and val together; keep the existing variables (sa, rel) and the WHERE all(r
IN relationships(...) ... ) checks when adding the new MATCHes to ensure only
active nodes are deleted.

---

Nitpick comments:
In
`@backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py`:
- Around line 60-69: Migration062.validate_migration is currently a no-op; add a
pre-check that queries the graph (via the provided db/InfrahubDatabase) for
SchemaGeneric nodes that still have the generate_template attribute and use that
to populate and return a meaningful MigrationResult (e.g., mark as not_needed
when none found or include a warning/info when some exist) before running
RemoveGenericGenerateTemplateQuery and
RemoveGenericGenerateTemplateSchemaAttributeQuery; reference Migration062,
validate_migration, MigrationResult, RemoveGenericGenerateTemplateQuery,
RemoveGenericGenerateTemplateSchemaAttributeQuery, and the
SchemaGeneric·generate_template attribute when implementing the check.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py (1)

56-63: Consider OPTIONAL MATCH for child attributes to avoid silent no-ops.

Line 57 uses a required MATCH for child attributes and values. If any SchemaAttribute child Attribute node happens to lack a HAS_VALUE edge, the entire MATCH fails for that row, and sa/rel won't be deleted at all (the query silently does nothing). An OPTIONAL MATCH with a null-safe cleanup would be more defensive:

Proposed fix
 // Find child Attribute nodes and their value nodes
-MATCH (sa)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[:HAS_VALUE]->(val)
-// Delete the SchemaAttribute, Relationship node, and child Attributes
-DETACH DELETE sa, rel, attr
-// Clean up orphaned value nodes (Boolean nodes are shared and will still have edges)
-WITH val
-WHERE NOT EXISTS { MATCH (val)-[]-() }
-DELETE val
+OPTIONAL MATCH (sa)-[:HAS_ATTRIBUTE]->(attr:Attribute)
+OPTIONAL MATCH (attr)-[:HAS_VALUE]->(val)
+// Delete the SchemaAttribute, Relationship node, and child Attributes
+DETACH DELETE sa, rel
+WITH attr, val
+WHERE attr IS NOT NULL
+DETACH DELETE attr
+WITH val
+WHERE val IS NOT NULL AND NOT EXISTS { MATCH (val)-[]-() }
+DELETE val

In practice, every Attribute should have a value node, so the current code works for the expected data shape. This is a robustness suggestion only.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py`
around lines 56 - 63, The current required MATCH for child Attribute/value
(MATCH (sa)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[:HAS_VALUE]->(val)) can cause
the row to be skipped if an Attribute lacks a HAS_VALUE edge; change it to an
OPTIONAL MATCH for the attr->val relationship (keep the parent match for
sa/rel/attr) so sa/rel/attr are still deleted even when val is null, then adjust
the subsequent WITH/WHERE cleanup to only attempt deleting val when it is not
null (e.g., pass val through the WITH and conditionally run the orphan check
WHERE NOT EXISTS { MATCH (val)-[]-() } DELETE val).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@backend/infrahub/core/migrations/graph/m062_remove_generic_generate_template.py`:
- Around line 56-63: The current required MATCH for child Attribute/value (MATCH
(sa)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[:HAS_VALUE]->(val)) can cause the row
to be skipped if an Attribute lacks a HAS_VALUE edge; change it to an OPTIONAL
MATCH for the attr->val relationship (keep the parent match for sa/rel/attr) so
sa/rel/attr are still deleted even when val is null, then adjust the subsequent
WITH/WHERE cleanup to only attempt deleting val when it is not null (e.g., pass
val through the WITH and conditionally run the orphan check WHERE NOT EXISTS {
MATCH (val)-[]-() } DELETE val).

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":401,"request":{"method":"PATCH","url":"https://api.github.com/repos/opsmill/infrahub/issues/comments/3896602838","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> An error occurred during the review process. Please try again later.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n## Walkthrough\n\nGRAPH_VERSION bumped to 62 and a new migration (Migration062) added to delete `generate_template` attributes from SchemaGeneric instances and their SchemaAttribute definitions. The `generate_template` attribute was removed from internal schema definitions and from public API/OpenAPI/types. Schema branch logic and frontend schema viewer were narrowed to operate on Node schemas for template generation. Documentation and examples were updated to indicate `generate_template` applies only to nodes. Tests were added for the migration, existing schema tests were renamed/expanded, and one integration test suite concerning generic-template inheritance was removed.\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (4 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                                                                                                                                                                                                    |\n| :------------------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|         Title check        | ✅ Passed | The title clearly and concisely describes the main change: preventing setting generate_template: true on generics. It accurately reflects the primary objective of the PR.                                                                     |\n|      Description check     | ✅ Passed | The description comprehensively covers all key sections: Why (problem and goal), What changed (behavioral and implementation details), How to review, How to test, Impact & rollout, and checklist items completed.                            |\n|     Linked Issues check    | ✅ Passed | The PR directly addresses issue `#8371` by removing the generate_template attribute from GenericSchema to prevent invalid GraphQL schema generation. All code changes align with the stated objective of blocking generate_template on generics. |\n| Out of Scope Changes check | ✅ Passed | All changes are directly scoped to removing generate_template from GenericSchema and related updates. No unrelated modifications detected; test adaptations and documentation changes are necessary consequences of the primary change.        |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=opsmill/infrahub&utm_content=8379)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":1}},"response":{"url":"https://api.github.com/repos/opsmill/infrahub/issues/comments/3896602838","status":401,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","connection":"close","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Tue, 17 Feb 2026 17:14:15 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-media-type":"github.v3; format=json","x-github-request-id":"2850:114C2C:834628:234DFA1:6994A1E7","x-xss-protection":"0"},"data":{"message":"Bad credentials","documentation_url":"https://docs.github.com/rest","status":"401"}}}

Comment on lines +23 to +27
MATCH (sg:SchemaGeneric)-[:HAS_ATTRIBUTE]->(attr:Attribute {name: "generate_template"})-[:HAS_VALUE]->(val)
DETACH DELETE attr
WITH val
WHERE NOT EXISTS { MATCH (val)-[]-() }
DELETE val
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can just do

MATCH (sg:SchemaGeneric)-[:HAS_ATTRIBUTE]->(attr:Attribute {name: "generate_template"})
WITH DISTINCT attr
DETACH DELETE attr

b/c the value would always just be either True or False and I think you can assume those AttributeValue vertices are used elsewhere

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

Labels

group/backend Issue related to the backend (API Server, Git Agent) group/frontend Issue related to the frontend (React) type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: using generate_template: True on a GenericSchema breaks the GraphQL schema (and UI)

3 participants