Skip to content

feat(ensapi): add tracing support with Pothos plugins and enhance GraphQL execution tracing#1855

Merged
shrugs merged 13 commits intomainfrom
1757-omnigraph-pothos-instrumentation
Apr 1, 2026
Merged

feat(ensapi): add tracing support with Pothos plugins and enhance GraphQL execution tracing#1855
shrugs merged 13 commits intomainfrom
1757-omnigraph-pothos-instrumentation

Conversation

@djstrong
Copy link
Copy Markdown
Contributor

@djstrong djstrong commented Mar 31, 2026

Lite PR

Summary

  • Add OTel tracing to ENSApi GraphQL (Pothos resolver spans + graphql.execute span).
  • Add find-domains.* manual spans for COUNT, paginated SELECT, and dataloader load.

Why

  • Make GraphQL performance debuggable beyond HTTP-level spans.

Testing

  • Ran test:integration and inspect traces

Notes for Reviewer (Optional)

  • Main logic: apps/ensapi/src/graphql-api/lib/find-domains/find-domains-resolver.ts.
  • New variables:
    • OTEL_EXPORTER_OTLP_ENDPOINT: set to enable exporting spans (otherwise spans are not exported).
    • OTEL_DEBUG: set to enable OTel diagnostic logging

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

…phQL execution tracing

- Integrated `@pothos/plugin-tracing` and `@pothos/tracing-opentelemetry` into the GraphQL API.
- Updated package dependencies in `package.json` and `pnpm-lock.yaml`.
- Implemented tracing in the GraphQL execution flow and added active span handling in resolvers.
- Enhanced configuration for tracing options based on environment variables.
- Adjusted test timeout in `config.singleton.test.ts` for improved stability.
Copilot AI review requested due to automatic review settings March 31, 2026 20:38
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 31, 2026

⚠️ No Changeset found

Latest commit: 0c23ec5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Apr 1, 2026 8:39pm
ensnode.io Skipped Skipped Apr 1, 2026 8:39pm
ensrainbow.io Skipped Skipped Apr 1, 2026 8:39pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OpenTelemetry-based tracing across the ensapi GraphQL builder and resolvers, refines async span helper typings, adds Pothos tracing dependencies, adjusts a test timeout, renames a Yoga logger, and makes integration tests bail on first failure.

Changes

Cohort / File(s) Summary
Dependencies
apps/ensapi/package.json
Added @pothos/plugin-tracing and @pothos/tracing-opentelemetry dependencies.
Span utilities
apps/ensapi/src/lib/instrumentation/auto-span.ts
Refined async span helper signatures to use explicit result type T and narrowed callback type (span: Span) => Promise<T>.
Schema builder & Yoga
apps/ensapi/src/omnigraph-api/builder.ts, apps/ensapi/src/omnigraph-api/yoga.ts
Wired OpenTelemetry + Pothos tracing into the schema builder with custom span naming/args handling; renamed Yoga logger to omnigraph and passed a plugins array to createYoga.
Resolvers & schema instrumentation
apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts, apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts, apps/ensapi/src/omnigraph-api/schema/domain.ts
Instrumented key operations (totalCount, connection execution, dataloader loads, parallel v1/v2 lookups, batch DB loads) with active spans and added span attributes and nested spans.
Tests
apps/ensapi/src/config/config.singleton.test.ts
Increased per-test timeout for a DB-init test to 10,000 ms.
UI label
apps/ensadmin/src/app/@breadcrumbs/(apis)/api/omnigraph/page.tsx
Changed breadcrumb label to “Omnigraph API (ENS v1 + v2)”.
CI / Orchestrator
packages/integration-test-env/src/orchestrator.ts
Modified integration test invocation to pnpm test:integration -- --bail 1 to stop on first failure.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant Yoga as Yoga (GraphQL Server)
    participant Builder as Schema Builder
    participant Tracer as OpenTelemetry Tracer
    participant Resolver as Resolver
    participant DB as Database / Dataloader

    Client->>Yoga: send GraphQL request
    activate Yoga
    Yoga->>Builder: execute operation
    activate Builder
    Builder->>Tracer: start field span
    activate Tracer
    Builder->>Resolver: invoke resolver
    activate Resolver
    Resolver->>Tracer: start child span (e.g., connection / dataloader)
    Resolver->>DB: execute DB query or dataloader.load
    activate DB
    DB-->>Resolver: return results
    deactivate DB
    Resolver->>Tracer: end child span (set attributes)
    Resolver-->>Builder: return resolved value
    deactivate Resolver
    Builder->>Tracer: end field span
    deactivate Tracer
    Builder-->>Yoga: response
    deactivate Builder
    Yoga-->>Client: GraphQL response
    deactivate Yoga
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hop through spans with whiskered delight,

I nest each trace from morning to night,
Builders, resolvers, and DB all align,
Omnigraph hums as each span shines,
A tiny rabbit logs observability's light.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding tracing support to ENSApi GraphQL using Pothos plugins and enhancing execution tracing, which aligns with all major file changes (dependencies, instrumentation, schema, and builder updates).
Description check ✅ Passed The PR description follows the template structure with all required sections completed: summary (bullet points of key changes), why (reasoning), testing (how validated), notes for reviewer, and a checked pre-review checklist. All sections are substantive rather than empty.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 1757-omnigraph-pothos-instrumentation

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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds GraphQL tracing instrumentation to ENS API using Pothos tracing plugins and custom Yoga execution spans, with env-driven toggles.

Changes:

  • Add @pothos/plugin-tracing and @pothos/tracing-opentelemetry dependencies.
  • Enable Pothos field-level tracing (conditionally) and add a Yoga execution tracing plugin (conditionally).
  • Add explicit span wrappers around findDomains resolver DB/query/dataloader steps; increase a test timeout for stability.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/ensapi/package.json Adds Pothos tracing dependencies.
pnpm-lock.yaml Locks new Pothos tracing packages and their peer deps.
apps/ensapi/src/graphql-api/builder.ts Conditionally enables Pothos TracingPlugin + OTel wrapper.
apps/ensapi/src/graphql-api/yoga.ts Adds Yoga execution-level tracing span with optional source capture.
apps/ensapi/src/graphql-api/lib/find-domains/find-domains-resolver.ts Wraps key resolver steps in spans for better visibility.
apps/ensapi/src/lib/instrumentation/auto-span.ts Fixes async span helper generic typing; minor touched-area comment.
apps/ensapi/src/config/config.singleton.test.ts Increases test timeout to reduce flakiness.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

apps/ensapi/src/lib/instrumentation/auto-span.ts:21

  • Spelling: "provded" -> "provided" in the comment (helps keep inline docs clear).
  return tracer.startActiveSpan(name, async (span) => {
    // add provded args to span attributes
    for (const [key, value] of Object.entries(args)) {
      span.setAttribute(key, value);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 31, 2026 20:42 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 31, 2026 20:42 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 31, 2026 20:42 Inactive
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensapi/src/graphql-api/yoga.ts`:
- Around line 19-33: The code currently allows capturing full GraphQL source
into spans when graphqlTracingIncludeSource is true, which risks leaking
sensitive literals in production; update the logic so AttributeNames.SOURCE is
only included when graphqlTracingIncludeSource is true AND the process is not
running in production (e.g., process.env.NODE_ENV !== "production" or an
equivalent guard), then use that guarded flag inside executionTracingPlugin
where graphqlTracer.startActiveSpan is called (references:
graphqlTracingIncludeSource, executionTracingPlugin,
graphqlTracer.startActiveSpan, SpanNames.EXECUTE, AttributeNames.SOURCE) so
source capture cannot be enabled in prod by env drift/misconfiguration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 29d83590-0567-404d-839a-7560a038331b

📥 Commits

Reviewing files that changed from the base of the PR and between 677db8b and 662a270.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/ensapi/package.json
  • apps/ensapi/src/config/config.singleton.test.ts
  • apps/ensapi/src/graphql-api/builder.ts
  • apps/ensapi/src/graphql-api/lib/find-domains/find-domains-resolver.ts
  • apps/ensapi/src/graphql-api/yoga.ts
  • apps/ensapi/src/lib/instrumentation/auto-span.ts

@djstrong djstrong marked this pull request as ready for review April 1, 2026 15:07
@djstrong djstrong requested a review from a team as a code owner April 1, 2026 15:07
Copilot AI review requested due to automatic review settings April 1, 2026 15:07
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR adds OpenTelemetry tracing to the ENSApi GraphQL layer: Pothos resolver-level spans via @pothos/plugin-tracing + @pothos/tracing-opentelemetry, a graphql.execute span via a Yoga plugin, and three manual spans inside find-domains-resolver.ts (totalCount, connection, dataloader-load). All new behaviour is opt-in behind the ENSAPI_GRAPHQL_TRACING environment variable, keeping the default path unchanged.

Key findings:

  • The executionTracingPlugin in yoga.ts calls span.recordException(error) on failure but never calls span.setStatus({ code: SpanStatusCode.ERROR }). Per the OTel spec, recordException only adds an event — the span status stays UNSET (displayed as OK) unless explicitly set. This means error executions will appear successful in tracing backends.
  • The graphqlTracingEnabled env-var parsing (=== "1" || === "true") is copy-pasted identically into both builder.ts and yoga.ts rather than being shared from a single location.
  • ENSAPI_GRAPHQL_TRACING and ENSAPI_GRAPHQL_TRACING_SOURCE are read directly from process.env instead of being threaded through the typed EnsApiEnvironment interface used by the rest of the config system.
  • The createOpenTelemetryWrapper call in builder.ts runs unconditionally at module load time, even when tracing is disabled.

Confidence Score: 4/5

Safe to merge after fixing the missing span status in the error handler; the main application path is unaffected since tracing is opt-in.

One P1 defect: the executionTracingPlugin does not set SpanStatusCode.ERROR on the span when an exception is caught, so error executions will silently appear as successful spans. Since the primary purpose of this PR is correct observability, this should be fixed before merging. All other findings are P2 style/consistency suggestions.

apps/ensapi/src/graphql-api/yoga.ts — missing span.setStatus(SpanStatusCode.ERROR) in the error handler of executionTracingPlugin.

Important Files Changed

Filename Overview
apps/ensapi/src/graphql-api/yoga.ts Adds an executionTracingPlugin that wraps GraphQL execution in an OTel span; error handler is missing span.setStatus(ERROR), causing error spans to appear as OK in tracing backends.
apps/ensapi/src/graphql-api/builder.ts Conditionally wires in Pothos TracingPlugin and createOpenTelemetryWrapper; graphqlTracingEnabled parsing is duplicated from yoga.ts and createSpan is initialised unconditionally.
apps/ensapi/src/graphql-api/lib/find-domains/find-domains-resolver.ts Wraps totalCount, paginated SELECT, and dataloader load in withActiveSpanAsync spans; implementation is correct and consistent with the existing span helper.
apps/ensapi/src/lib/instrumentation/tracer.ts New file exporting a shared graphqlTracer from trace.getTracer("ensnode-graphql"); clean and correct.
apps/ensapi/src/lib/instrumentation/auto-span.ts Refactors generic type parameters for withActiveSpanAsync and withSpanAsync to be simpler; no functional changes.
apps/ensapi/src/config/config.singleton.test.ts Adds a 15-second timeout to a slow integration test; appropriate fix.
apps/ensapi/package.json Adds @pothos/plugin-tracing and @pothos/tracing-opentelemetry dependencies required by the new tracing integration.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Yoga as GraphQL Yoga
    participant ExecPlugin as executionTracingPlugin
    participant OTel as OTel Tracer
    participant Pothos as Pothos Resolvers
    participant Resolver as find-domains-resolver
    participant DB as Database / Dataloader

    Client->>Yoga: HTTP POST /graphql
    Yoga->>ExecPlugin: onExecute (if ENSAPI_GRAPHQL_TRACING=1)
    ExecPlugin->>OTel: startActiveSpan("graphql.execute")
    ExecPlugin->>Pothos: executeFn(options)
    Pothos->>OTel: createSpan per resolver (via TracingPlugin)
    Pothos->>Resolver: resolveFindDomains()
    Resolver->>OTel: startActiveSpan("find-domains.totalCount")
    OTel-->>Resolver: span
    Resolver->>DB: SELECT COUNT(*)
    DB-->>Resolver: count
    Resolver->>OTel: span.end()
    Resolver->>OTel: startActiveSpan("find-domains.connection")
    OTel-->>Resolver: span
    Resolver->>DB: SELECT paginated
    DB-->>Resolver: rows
    Resolver->>OTel: span.end()
    Resolver->>OTel: startActiveSpan("find-domains.dataloader-load")
    OTel-->>Resolver: span
    Resolver->>DB: dataloader.loadMany(ids)
    DB-->>Resolver: Domain entities
    Resolver->>OTel: span.end()
    Resolver-->>Pothos: DomainWithOrderValue[]
    Pothos-->>ExecPlugin: ExecutionResult
    ExecPlugin->>OTel: span.end() (graphql.execute)
    ExecPlugin-->>Yoga: ExecutionResult
    Yoga-->>Client: HTTP 200
Loading

Reviews (1): Last reviewed commit: "feat(tracer): add initial GraphQL tracer..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shrugs
Copy link
Copy Markdown
Collaborator

shrugs commented Apr 1, 2026

image

Copy link
Copy Markdown
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ensapi/src/omnigraph-api/schema/domain.ts (1)

79-97: 🧹 Nitpick | 🔵 Trivial

Inconsistent tracing: DomainInterfaceRef.load is not instrumented.

The ENSv1DomainRef and ENSv2DomainRef loaders are wrapped with withSpanAsync, but DomainInterfaceRef.load performs similar database queries without tracing. For consistent observability, consider wrapping this loader as well.

♻️ Suggested fix
 export const DomainInterfaceRef = builder.loadableInterfaceRef("Domain", {
-  load: async (ids: DomainId[]): Promise<(ENSv1Domain | ENSv2Domain)[]> => {
-    const [v1Domains, v2Domains] = await Promise.all([
-      ensDb.query.v1Domain.findMany({
-        where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv1DomainId
-        with: { label: true },
-      }),
-      ensDb.query.v2Domain.findMany({
-        where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv2DomainId
-        with: { label: true },
-      }),
-    ]);
-
-    return [...v1Domains, ...v2Domains];
-  },
+  load: (ids: DomainId[]): Promise<(ENSv1Domain | ENSv2Domain)[]> =>
+    withSpanAsync(tracer, "Domain.load", { count: ids.length }, async () => {
+      const [v1Domains, v2Domains] = await Promise.all([
+        ensDb.query.v1Domain.findMany({
+          where: (t, { inArray }) => inArray(t.id, ids as any),
+          with: { label: true },
+        }),
+        ensDb.query.v2Domain.findMany({
+          where: (t, { inArray }) => inArray(t.id, ids as any),
+          with: { label: true },
+        }),
+      ]);
+
+      return [...v1Domains, ...v2Domains];
+    }),
   toKey: getModelId,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensapi/src/omnigraph-api/schema/domain.ts` around lines 79 - 97, The
DomainInterfaceRef.load implementation lacks tracing; wrap its async load
function with withSpanAsync (the same helper used for ENSv1DomainRef and
ENSv2DomainRef) so the database queries (ensDb.query.v1Domain.findMany and
ensDb.query.v2Domain.findMany) execute inside a span; give the span a clear name
like "DomainInterfaceRef.load" and include relevant attributes (e.g., ids length
or model ids via getModelId), ensure errors continue to propagate and preserve
existing options (toKey: getModelId, cacheResolved, sort).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensapi/src/omnigraph-api/builder.ts`:
- Around line 27-45: The span naming in createSpan's onSpan callback assumes
info.returnType has a .name and that parent.node.id exists; update onSpan to
defensively resolve the named type (use GraphQL's getNamedType on
info.returnType) to obtain typename only if present, and check that parent and
parent.node and parent.node.id are defined before using them; if either value is
missing fall back to a safe name (e.g., info.parentType.name or
`${info.parentType.name}.${info.fieldName}`) so no unsafe (info.returnType as
any).name or (parent as any).node.id assertions can throw at runtime.

In `@apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts`:
- Around line 74-82: The inner spans started via withActiveSpanAsync (tracer,
"v1_getDomainId", {}, ...) and the conditional v2 span ("v2_getDomainId", {},
...) lack useful attributes; update both calls to pass an attributes object
including the lookup name (e.g., { name }) so the span for v1_getDomainId and
v2_getDomainId contains the interpreted domain name being queried (affecting the
calls that invoke v1_getDomainIdByInterpretedName and
v2_getDomainIdByInterpretedName).

In `@apps/ensapi/src/omnigraph-api/yoga.ts`:
- Around line 43-48: The plugins array in yoga.ts currently leaves
maxTokensPlugin, maxDepthPlugin, and maxAliasesPlugin commented out; enable and
configure these plugins (maxTokensPlugin, maxDepthPlugin, maxAliasesPlugin) for
production to protect against malicious GraphQL queries by uncommenting or
wiring them into the plugins array and supplying appropriate configuration
values (e.g., maxOperationTokens, maxOperationDepth, maxOperationAliases) or
feature flags, and ensure any environment-based toggles or allowlists are
implemented so the plugins can be turned on in production while remaining off
during local/tracing runs.

---

Outside diff comments:
In `@apps/ensapi/src/omnigraph-api/schema/domain.ts`:
- Around line 79-97: The DomainInterfaceRef.load implementation lacks tracing;
wrap its async load function with withSpanAsync (the same helper used for
ENSv1DomainRef and ENSv2DomainRef) so the database queries
(ensDb.query.v1Domain.findMany and ensDb.query.v2Domain.findMany) execute inside
a span; give the span a clear name like "DomainInterfaceRef.load" and include
relevant attributes (e.g., ids length or model ids via getModelId), ensure
errors continue to propagate and preserve existing options (toKey: getModelId,
cacheResolved, sort).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b950a43d-a6b2-4cb5-b6ee-74d67e2ed3a0

📥 Commits

Reviewing files that changed from the base of the PR and between 6154b60 and 0199b4f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/ensadmin/src/app/@breadcrumbs/(apis)/api/omnigraph/page.tsx
  • apps/ensapi/package.json
  • apps/ensapi/src/omnigraph-api/builder.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts
  • apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts
  • apps/ensapi/src/omnigraph-api/schema/domain.ts
  • apps/ensapi/src/omnigraph-api/yoga.ts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (3)

packages/integration-test-env/src/orchestrator.ts:344

  • When running a pnpm script, additional CLI args are typically forwarded to the underlying command only after a -- delimiter. As written, --bail 1 may be parsed by pnpm itself instead of being passed through to vitest, causing the orchestrator to fail. Consider invoking pnpm run test:integration -- --bail 1 (or inserting "--" before --bail).
  execaSync("pnpm", ["test:integration", "--bail", "1"], {
    cwd: MONOREPO_ROOT,
    stdio: "inherit",
    env: {
      ENSNODE_URL: `http://localhost:${ENSAPI_PORT}`,
    },
  });

apps/ensapi/src/lib/instrumentation/auto-span.ts:21

  • Typo in comment: "provded" should be "provided".
    // add provded args to span attributes
    for (const [key, value] of Object.entries(args)) {
      span.setAttribute(key, value);

apps/ensapi/src/lib/instrumentation/auto-span.ts:85

  • Typo in comment: "provded" should be "provided".
  // add provded args to span attributes
  for (const [key, value] of Object.entries(args)) {
    span.setAttribute(key, value);
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 1, 2026 20:05 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 1, 2026 20:05 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 1, 2026 20:05 Inactive
Copilot AI review requested due to automatic review settings April 1, 2026 20:09
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 1, 2026 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 1, 2026 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 1, 2026 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 1, 2026 20:12 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 1, 2026 20:12 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 1, 2026 20:12 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 1, 2026 20:32 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 1, 2026 20:32 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 1, 2026 20:32 Inactive
Copy link
Copy Markdown
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ensapi/src/omnigraph-api/schema/domain.ts (1)

79-97: 🧹 Nitpick | 🔵 Trivial

Missing tracing on DomainInterfaceRef.load for consistency.

ENSv1DomainRef and ENSv2DomainRef loaders are wrapped with withSpanAsync, but DomainInterfaceRef.load performs similar database queries without tracing. This creates an observability gap when domains are loaded through the interface.

♻️ Suggested fix to add tracing
 export const DomainInterfaceRef = builder.loadableInterfaceRef("Domain", {
   load: async (ids: DomainId[]): Promise<(ENSv1Domain | ENSv2Domain)[]> => {
-    const [v1Domains, v2Domains] = await Promise.all([
-      ensDb.query.v1Domain.findMany({
-        where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv1DomainId
-        with: { label: true },
-      }),
-      ensDb.query.v2Domain.findMany({
-        where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv2DomainId
-        with: { label: true },
-      }),
-    ]);
+    const [v1Domains, v2Domains] = await withSpanAsync(
+      tracer,
+      "Domain.load",
+      { count: ids.length },
+      () =>
+        Promise.all([
+          ensDb.query.v1Domain.findMany({
+            where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv1DomainId
+            with: { label: true },
+          }),
+          ensDb.query.v2Domain.findMany({
+            where: (t, { inArray }) => inArray(t.id, ids as any), // ignore downcast to ENSv2DomainId
+            with: { label: true },
+          }),
+        ]),
+    );
 
     return [...v1Domains, ...v2Domains];
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensapi/src/omnigraph-api/schema/domain.ts` around lines 79 - 97,
DomainInterfaceRef.load is performing DB queries without tracing; wrap the load
implementation in the same withSpanAsync tracing helper used by ENSv1DomainRef
and ENSv2DomainRef so the queries are instrumented. Specifically, change the
load function passed to builder.loadableInterfaceRef("Domain") to call
withSpanAsync (e.g., withSpanAsync("DomainInterfaceRef.load", async () => { ...
})) around the Promise.all block, preserve returning [...v1Domains,
...v2Domains], keep toKey: getModelId, cacheResolved and sort settings, and
ensure TypeScript types for the async callback match
Promise<(ENSv1Domain|ENSv2Domain)[]> so tracing doesn’t alter the return type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensapi/src/omnigraph-api/builder.ts`:
- Around line 44-49: The span naming uses getNamedType(info.returnType) without
guarding for undefined, which can produce "undefined(id)"; update the logic
around getNamedType(info.returnType) in the branch where info.parentType.name
endsWith("Edge") and info.fieldName === "node" to read the type name defensively
(e.g., const named = getNamedType(info.returnType); const typename = named?.name
?? "UnknownType") and then call span.updateName(`${typename}(${id})`) so a
sensible fallback is used when getNamedType returns undefined.

---

Outside diff comments:
In `@apps/ensapi/src/omnigraph-api/schema/domain.ts`:
- Around line 79-97: DomainInterfaceRef.load is performing DB queries without
tracing; wrap the load implementation in the same withSpanAsync tracing helper
used by ENSv1DomainRef and ENSv2DomainRef so the queries are instrumented.
Specifically, change the load function passed to
builder.loadableInterfaceRef("Domain") to call withSpanAsync (e.g.,
withSpanAsync("DomainInterfaceRef.load", async () => { ... })) around the
Promise.all block, preserve returning [...v1Domains, ...v2Domains], keep toKey:
getModelId, cacheResolved and sort settings, and ensure TypeScript types for the
async callback match Promise<(ENSv1Domain|ENSv2Domain)[]> so tracing doesn’t
alter the return type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8b8eb342-60ff-4e2e-bcfe-2b90959ea980

📥 Commits

Reviewing files that changed from the base of the PR and between c3f9e41 and 5ba8d41.

📒 Files selected for processing (3)
  • apps/ensapi/src/omnigraph-api/builder.ts
  • apps/ensapi/src/omnigraph-api/schema/domain.ts
  • packages/integration-test-env/src/orchestrator.ts

Copilot AI review requested due to automatic review settings April 1, 2026 20:39
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 1, 2026 20:39 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 1, 2026 20:39 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 1, 2026 20:39 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

apps/ensapi/src/lib/instrumentation/auto-span.ts:21

  • The comment says "add provded args" (typo). Consider correcting to "add provided args" (appears in multiple helpers in this file).
    // add provded args to span attributes
    for (const [key, value] of Object.entries(args)) {
      span.setAttribute(key, value);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shrugs shrugs merged commit 3b324fd into main Apr 1, 2026
22 checks passed
@shrugs shrugs deleted the 1757-omnigraph-pothos-instrumentation branch April 1, 2026 20:46
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.

3 participants