fix: search anywhere crashes on SchemaNode UUID lookup#8942
fix: search anywhere crashes on SchemaNode UUID lookup#8942BeArchiTek wants to merge 16 commits intostablefrom
Conversation
The UUID search path in InfrahubSearchAnywhere returned any node regardless of namespace, including internal Schema/Internal nodes. The frontend then crashed with "Cannot read properties of null (reading 'kind')" because SchemaNode is not in the frontend schema registry. Backend: filter UUID search results by namespace, excluding Schema and Internal nodes — consistent with the string search path. Frontend: split NodesOptions into a schema-resolving wrapper and a details component to prevent useGetObject from being called with a null schema.
There was a problem hiding this comment.
1 issue found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="backend/tests/component/graphql/queries/test_search.py">
<violation number="1" location="backend/tests/component/graphql/queries/test_search.py:79">
P1: Custom agent: **Flag ad-hoc reproducer tests committed to CI (unmarked/flaky reproducer code)**
This is an unmarked reproducer test; mark it skip/xfail or gate it behind an explicit opt-in before committing it to CI.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
…crash' into 005-search-display-label
Phase 0 research + Phase 1 design artifacts: - research.md, data-model.md, quickstart.md, contracts/ Co-Authored-By: Claude Opus 4.6 <[email protected]>
24 tasks across 6 phases, organized by user story. Co-Authored-By: Claude Opus 4.6 <[email protected]>
…odes
UUID search now returns Schema and Internal namespace nodes with a
human-readable display_label. The frontend renders a simplified result
linking to /schema?kind={kind} instead of crashing on unknown schemas.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
7 issues found across 17 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/app/src/entities/navigation/ui/search-anywhere/search-nodes.tsx">
<violation number="1" location="frontend/app/src/entities/navigation/ui/search-anywhere/search-nodes.tsx:82">
P2: Use `constructPath` for the schema fallback URL instead of a manual query string. The current URL drops preserved query params (branch/datetime) and can mis-handle unencoded kinds.</violation>
</file>
<file name="dev/specs/005-search-display-label/quickstart.md">
<violation number="1" location="dev/specs/005-search-display-label/quickstart.md:9">
P1: The quickstart instructions reverse the intended UUID-search filtering behavior, which can reintroduce the Schema/Internal result-path crash/regression.</violation>
</file>
<file name="backend/tests/component/graphql/queries/test_search.py">
<violation number="1" location="backend/tests/component/graphql/queries/test_search.py:117">
P2: This UUID regression test now expects Schema/Internal nodes to be returned, which is the opposite of the crash fix. It should assert zero results so the test actually guards the exclusion behavior.</violation>
</file>
<file name="backend/infrahub/graphql/queries/search.py">
<violation number="1" location="backend/infrahub/graphql/queries/search.py:120">
P1: UUID search no longer filters out `Schema`/`Internal` nodes, so internal objects can be returned where search is expected to exclude them.</violation>
</file>
<file name="dev/specs/005-search-display-label/tasks.md">
<violation number="1" location="dev/specs/005-search-display-label/tasks.md:34">
P1: This task reverses the intended UUID filtering behavior by telling implementers to remove the Schema/Internal filter.</violation>
<violation number="2" location="dev/specs/005-search-display-label/tasks.md:36">
P1: This test task specifies assertions opposite to the intended UUID behavior, likely locking in a regression.</violation>
</file>
<file name="dev/specs/005-search-display-label/contracts/search-graphql.md">
<violation number="1" location="dev/specs/005-search-display-label/contracts/search-graphql.md:48">
P2: The UUID behavior table contradicts the implemented fix by saying Schema/Internal UUID searches return results; the contract should document zero results for those namespaces.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The entry was dropped during earlier betterer updates but CI needs it since the generated types.ts is not committed to git. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/app/.betterer.results">
<violation number="1">
P2: This change introduces a new TypeScript error into the Betterer baseline, which masks a real compile-time issue instead of resolving it.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
SchemaNode records have kind="SchemaNode" but describe another schema (e.g. CoreGroupAction). The frontend was using node.kind for the URL, navigating to the generic SchemaNode page instead of the described schema's page. Backend now exposes target_kind (composed from namespace + name attributes) for Schema records. Frontend uses target_kind for both the URL and the kind badge in the simplified view. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment |
| node_data = result.data["InfrahubSearchAnywhere"]["edges"][0]["node"] | ||
| assert node_data["id"] == internal_node.id | ||
| assert node_data["kind"] == "InternalWidget" | ||
| assert node_data["display_label"] is not None |
There was a problem hiding this comment.
the test should be able to assert what the display label is
| node_data = result.data["InfrahubSearchAnywhere"]["edges"][0]["node"] | ||
| assert node_data["display_label"] is not None | ||
| assert isinstance(node_data["display_label"], str) | ||
| assert len(node_data["display_label"]) > 0 |
| assert result.errors is None | ||
| assert result.data | ||
| assert result.data["InfrahubSearchAnywhere"]["count"] == 0 | ||
| assert result.data["InfrahubSearchAnywhere"]["edges"] == [] |
There was a problem hiding this comment.
doesn't seem to be introduced in this PR, but it seems like an anti-pattern that Internal schema objects are only included in the search results if the search term is the ID of the internal object. I would expect searching for the name of findable-widget here to return it
| "For Schema records (SchemaNode/SchemaGeneric), the kind of the schema they " | ||
| "describe so clients can link to that schema's page instead of the generic " | ||
| "SchemaNode/SchemaGeneric page." |
There was a problem hiding this comment.
this description of a GraphQL field shouldn't describe how the client works. maybe something like
"If kind is SchemaNode/SchemaGeneric, target_kind is set to the name of the schema (eg BuiltinTag)"
Summary
InfrahubSearchAnywherereturned any node regardless of namespace. When a user searched for a SchemaNode UUID (e.g. from a proposed change validation error), the backend returnedkind: "SchemaNode"which the frontend couldn't resolve, causing a crash. Added namespace filtering to excludeSchemaandInternalnodes — consistent with the string search path that already filters byCoreNode/CoreGroup.useGetObjectwas called with a null-asserted schema (schema!) before the null check, crashing ingetObjectQueryOptionswhen accessing.kindon null. SplitNodesOptionsinto a schema-resolving wrapper and a details component souseGetObjectis only called when schema is guaranteed non-null.Test plan
test_search_anywhere_by_uuid_excludes_internal_nodes— creates nodes withInternalandSchemanamespaces, verifies UUID search returns 0 results for bothsearch-nodes.test.tsx— verifiesNodesOptionsdoes not calluseGetObjectwhenuseSchemareturns nullSummary by cubic
Fixes Search Anywhere crashing on Schema/Internal UUIDs by returning those nodes with a
display_labeland atarget_kind, then rendering a simple result that links to the actual schema entry. Links preserve branch/datetime query params; text search and regular nodes are unchanged.New Features
display_labelandtarget_kindto searchNode; UUID search now returns Schema/Internal nodes with both fields.display_label/target_kindand usestarget_kindfor the link and kind badge in a simplified row (no extra fetch).display_label; text search still excludes Schema/Internal. Frontend tests verifytarget_kindrouting, label fallback, and regular node behavior.Bug Fixes
NodesOptionsinto a schema resolver and a details component souseGetObjectis never called with a null schema, preventing the crash.constructPathto keep existing branch/datetime query params.Nodetype to include the new fields consistently.artifacts/types.tsto keep CI passing.Written for commit 5cf67b6. Summary will update on new commits.