Skip to content

fix(sdk): defensive resource creation for otel v1, v2 resolution#647

Merged
nirga merged 6 commits intomainfrom
gk/otel-version-conflict
Aug 15, 2025
Merged

fix(sdk): defensive resource creation for otel v1, v2 resolution#647
nirga merged 6 commits intomainfrom
gk/otel-version-conflict

Conversation

@galkleinman
Copy link
Copy Markdown
Contributor

@galkleinman galkleinman commented Aug 15, 2025

Important

Improves tracing initialization with defensive resource creation and updates OpenTelemetry dependencies for compatibility.

  • Behavior:
    • In startTracing() in index.ts, adds defensive resource creation to handle OTLP serialization errors.
    • Ensures a valid service name is used, defaulting to unknown-service if not provided.
    • Emits warnings instead of errors when resource creation fails, using a fallback resource.
  • Dependencies:
    • Declares @opentelemetry/api, @opentelemetry/resources, @opentelemetry/sdk-trace-base, and @opentelemetry/exporter-trace-otlp-proto as non-optional peer dependencies in package.json.
    • Specifies compatible versions for these dependencies to prevent mismatches.

This description was created by Ellipsis for db16cd1. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • Bug Fixes

    • More reliable tracing initialization with safer resource creation and graceful fallbacks.
    • Ensures a valid service name to reduce startup/export failures.
    • Emits warnings instead of hard failures when resource construction is problematic.
  • Chores

    • Declared required OpenTelemetry packages as non-optional peer dependencies.
    • Specified compatible versions to avoid dependency mismatches during installation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Aug 15, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

Walkthrough

Adds OpenTelemetry peer dependency metadata to traceloop-sdk’s package.json and updates tracing initialization to precompute, validate, and fallback for an OpenTelemetry Resource (service.name) before using it in NodeSDK configuration.

Changes

Cohort / File(s) Summary
Packaging metadata
packages/traceloop-sdk/package.json
Added peerDependencies for four OpenTelemetry packages (@opentelemetry/api, @opentelemetry/resources, @opentelemetry/sdk-trace-base, @opentelemetry/exporter-trace-otlp-proto) and peerDependenciesMeta marking them non-optional.
Tracing resource initialization
packages/traceloop-sdk/src/lib/tracing/index.ts
Precompute a Resource (service.name) from appName / npm_package_name / default; validate in try/catch and fall back to a minimal Resource with a logged warning; use the validated/precomputed Resource in NodeSDK configuration instead of inlining resourceFromAttributes.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant TracingInit
  participant ResourceBuilder
  participant NodeSDK
  participant OTLPExporter

  App->>TracingInit: initTracing(appName?)
  TracingInit->>ResourceBuilder: build Resource (service.name)
  alt Resource valid
    ResourceBuilder-->>TracingInit: Resource
  else Fallback
    ResourceBuilder-->>TracingInit: Minimal Resource + warning
  end
  TracingInit->>NodeSDK: configure(resource)
  NodeSDK->>OTLPExporter: setup exporter
  App-->>NodeSDK: start
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Suggested reviewers

  • doronkopit5

Poem

I hop through traces with a careful nose,
I name the service where the warm light glows.
If Resource trembles, I stitch a seam,
Log a soft warning, then steady the beam.
Peer deps aligned — onward to OTLP we go! 🥕🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 42a627b and db16cd1.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/src/lib/tracing/index.ts (2 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch gk/otel-version-conflict

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to 11ad43a in 1 minute and 27 seconds. Click for details.
  • Reviewed 87 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/package.json:25
  • Draft comment:
    Duplicating opentelemetry packages as both dependencies and peerDependencies can lead to version conflicts. Verify if both are needed.
  • Reason this comment was not posted:
    Comment was on unchanged code.

Workflow ID: wflow_JAw8xpJU13maVBDE

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

diag.warn('Failed to create resource with resourceFromAttributes, using fallback', error);
resource = resourceFromAttributes({});
// Manually set the service name on the fallback resource
(resource as any).attributes = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid mutating resource attributes via a type cast. Consider using Resource.merge (or an official API) rather than (resource as any).attributes assignment.

Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed cf44602 in 44 seconds. Click for details.
  • Reviewed 46 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/index.ts:311
  • Draft comment:
    Stylistic update: The multi-line assignment for serviceName improves readability. Ensure it’s consistent with your project’s style.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/src/lib/tracing/index.ts:322
  • Draft comment:
    Good defensive checks on the resource object. Note that using '!resource' safely catches null values (since typeof null is 'object') – consider abstracting these checks into a helper if reused elsewhere.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
3. packages/traceloop-sdk/src/lib/tracing/index.ts:332
  • Draft comment:
    The diag.warn formatting update (using double quotes and trailing commas) improves clarity. Verify that the trailing comma complies with your linting rules.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_MZ3pqP0hhfKpHynY

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

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: 2

🧹 Nitpick comments (2)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

311-311: Consider honoring OTEL_SERVICE_NAME

Since many users set service.name via OTEL_SERVICE_NAME, include it in the precedence chain before falling back to npm_package_name or a default.

If you apply the previous diff, this is already addressed.

packages/traceloop-sdk/package.json (1)

31-44: peerDependenciesMeta with "optional": false is redundant and ignored

peerDependenciesMeta.optional only has meaning when true. Setting it to false provides no benefit and adds noise. Consider removing this block entirely or marking only truly optional peers as { "optional": true }.

-  "peerDependenciesMeta": {
-    "@opentelemetry/api": {
-      "optional": false
-    },
-    "@opentelemetry/resources": {
-      "optional": false
-    },
-    "@opentelemetry/sdk-trace-base": {
-      "optional": false
-    },
-    "@opentelemetry/exporter-trace-otlp-proto": {
-      "optional": false
-    }
-  },
+  // peerDependenciesMeta not needed unless marking peers as optional
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 16ab34d and 11ad43a.

📒 Files selected for processing (2)
  • packages/traceloop-sdk/package.json (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/index.ts (2 hunks)
🔇 Additional comments (2)
packages/traceloop-sdk/src/lib/tracing/index.ts (2)

342-342: LGTM: Using the precomputed resource in NodeSDK config

Passing the constructed resource into NodeSDK keeps initialization consistent and avoids repeated creation.


5-5: resourceFromAttributes is a stable public API in both OTel v1.x and v2.x
The function resourceFromAttributes is officially exported by @opentelemetry/resources in both major versions. There’s no breaking change or removal documented, and current guides (including the OTel JS docs and Azure Monitor examples) continue to use it. You can safely keep the existing import.

  • Official OTel JS documentation shows resourceFromAttributes in v1.x and v2.x
  • Recent v2.0 blog posts and migration notes make no mention of its removal
  • Azure Monitor (June 2025) sample code imports and uses it directly

No changes required here—please ignore the original suggestion.

Likely an incorrect or invalid review comment.

Comment on lines +25 to +30
"peerDependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/resources": "^2.0.0",
"@opentelemetry/sdk-trace-base": "^2.0.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.203.0"
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Peer ranges should reflect v1 and v2 compatibility to match the PR objective

Declaring only v2 for several OpenTelemetry peers contradicts the “v1, v2 resolution” goal and can force consumers onto v2. Use union ranges to support both v1 and v2 where applicable.

Apply this diff (adjust minimal v1 versions to those you actually support):

   "peerDependencies": {
     "@opentelemetry/api": "^1.9.0",
-    "@opentelemetry/resources": "^2.0.0",
-    "@opentelemetry/sdk-trace-base": "^2.0.0",
-    "@opentelemetry/exporter-trace-otlp-proto": "^0.203.0"
+    "@opentelemetry/resources": "^1.10.0 || ^2.0.0",
+    "@opentelemetry/sdk-trace-base": "^1.10.0 || ^2.0.0",
+    "@opentelemetry/exporter-trace-otlp-proto": "^0.40.0 || ^0.203.0"
   },

Also, consider removing these packages from "dependencies" to avoid duplicate installs and version skew. If needed for local builds/tests, move them to "devDependencies".

Please verify Node.js engine compatibility: OTel v2 typically requires Node >= 18. If you retain v2 ranges, the "engines.node": ">=14" may be misleading for consumers on Node 14/16.


🌐 Web query:

What Node.js versions are required by @opentelemetry/resources v2.x and @opentelemetry/sdk-trace-base v2.x?

💡 Result:

@opentelemetry/resources v2.x and @opentelemetry/sdk-trace-base v2.x require a minimum Node.js version of 18.19.0 or 20.6.0 and above[1]. This requirement applies to all stable OpenTelemetry JS SDK v2.x packages, including these two[1].

  • The requirement is formally described as:
    Node.js: ^18.19.0 || >=20.6.0
  • Node.js 14 and 16 are no longer supported[1].
  • This minimum is in line with OpenTelemetry JS SDK v2.x, under which both @opentelemetry/resources and @opentelemetry/sdk-trace-base are part[1].

For context:

  • This version bump was introduced with the release of OpenTelemetry JS SDK 2.0 and covers releases >=2.0.0 for stable packages (including these)[1].
  • You must use TypeScript 5.0.4 or newer if you use TypeScript[1].

If you intend to use these packages, ensure your application is running Node 18.19.0+, or 20.6.0+ to guarantee support and compatibility[1][7].

Citations:


Bump OpenTelemetry peer ranges for v1/v2 support and enforce Node ≥18.19.0

  • Adjust peerDependencies to allow both v1 (e.g. ^1.10.0) and v2 (^2.0.0) for the OTel packages.
  • Move any OpenTelemetry packages from "dependencies" to "devDependencies" to avoid duplicate installs and version skew.
  • Update "engines.node" in package.json from " >=14" to " >=18.19.0" (v2.x requires Node 18.19.0 or newer).
   "peerDependencies": {
     "@opentelemetry/api": "^1.9.0",
-    "@opentelemetry/resources": "^2.0.0",
-    "@opentelemetry/sdk-trace-base": "^2.0.0",
-    "@opentelemetry/exporter-trace-otlp-proto": "^0.203.0"
+    "@opentelemetry/resources": "^1.10.0 || ^2.0.0",
+    "@opentelemetry/sdk-trace-base": "^1.10.0 || ^2.0.0",
+    "@opentelemetry/exporter-trace-otlp-proto": "^0.40.0 || ^0.203.0"
   },
-  "dependencies": {
-    /* …OTel packages… */
-  },
-  "engines": {
-    "node": ">=14"
-  }
+  "devDependencies": {
+    /* Move OTel packages here if used only for build/tests */
+  },
+  "engines": {
+    "node": ">=18.19.0"
+  }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
packages/traceloop-sdk/package.json lines 25-30: update peerDependencies to
accept both OpenTelemetry v1 and v2 (e.g. set each OTel package to "^1.10.0 ||
^2.0.0"), move any OpenTelemetry packages currently listed under "dependencies"
into "devDependencies" to avoid duplicate installs/version skew, and change
"engines.node" from ">=14" to ">=18.19.0"; ensure package.json still validates
(run npm install / npm pack) after edits.

Comment on lines +310 to +339
// Create resource with defensive handling for OTLP serialization
const serviceName = options.appName || process.env.npm_package_name || "unknown-service";
let resource: Resource;

try {
resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: serviceName,
});

// Defensive check to prevent OTLP serialization errors
// Ensure the resource has the expected structure for createResourceMap
if (!resource || typeof resource !== 'object') {
throw new Error('Invalid resource object');
}

// Ensure resource has required properties for OTLP export
if (!resource.attributes || typeof resource.attributes !== 'object') {
throw new Error('Resource missing attributes');
}

} catch (error) {
// Fallback: create a basic resource manually
diag.warn('Failed to create resource with resourceFromAttributes, using fallback', error);
resource = resourceFromAttributes({});
// Manually set the service name on the fallback resource
(resource as any).attributes = {
[ATTR_SERVICE_NAME]: serviceName,
...((resource as any).attributes || {}),
};
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify and harden resource creation; remove fallback that re-invokes the same failing path and avoid mutating resource.attributes

  • The fallback path re-calls resourceFromAttributes({}), which will fail for the same reason as the primary call.
  • Directly mutating (resource as any).attributes is brittle and may break with internal changes or readonly properties. Construct a Resource once with the attributes you need (works in OTel v1 and v2) and let NodeSDK merge with defaults.

Apply this diff:

-  // Create resource with defensive handling for OTLP serialization
-  const serviceName = options.appName || process.env.npm_package_name || "unknown-service";
-  let resource: Resource;
-  
-  try {
-    resource = resourceFromAttributes({
-      [ATTR_SERVICE_NAME]: serviceName,
-    });
-    
-    // Defensive check to prevent OTLP serialization errors
-    // Ensure the resource has the expected structure for createResourceMap
-    if (!resource || typeof resource !== 'object') {
-      throw new Error('Invalid resource object');
-    }
-    
-    // Ensure resource has required properties for OTLP export
-    if (!resource.attributes || typeof resource.attributes !== 'object') {
-      throw new Error('Resource missing attributes');
-    }
-    
-  } catch (error) {
-    // Fallback: create a basic resource manually
-    diag.warn('Failed to create resource with resourceFromAttributes, using fallback', error);
-    resource = resourceFromAttributes({});
-    // Manually set the service name on the fallback resource
-    (resource as any).attributes = {
-      [ATTR_SERVICE_NAME]: serviceName,
-      ...((resource as any).attributes || {}),
-    };
-  }
+  // Create resource with a construction compatible across OTel v1 and v2
+  const serviceName =
+    options.appName ||
+    process.env.OTEL_SERVICE_NAME ||
+    process.env.npm_package_name ||
+    "unknown-service";
+  const resource: Resource = new Resource({ [ATTR_SERVICE_NAME]: serviceName });

Notes:

  • NodeSDK will merge this with its default resource; no need to mutate attributes post-construction.
  • Added support for the standard OTEL_SERVICE_NAME env variable.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Create resource with defensive handling for OTLP serialization
const serviceName = options.appName || process.env.npm_package_name || "unknown-service";
let resource: Resource;
try {
resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: serviceName,
});
// Defensive check to prevent OTLP serialization errors
// Ensure the resource has the expected structure for createResourceMap
if (!resource || typeof resource !== 'object') {
throw new Error('Invalid resource object');
}
// Ensure resource has required properties for OTLP export
if (!resource.attributes || typeof resource.attributes !== 'object') {
throw new Error('Resource missing attributes');
}
} catch (error) {
// Fallback: create a basic resource manually
diag.warn('Failed to create resource with resourceFromAttributes, using fallback', error);
resource = resourceFromAttributes({});
// Manually set the service name on the fallback resource
(resource as any).attributes = {
[ATTR_SERVICE_NAME]: serviceName,
...((resource as any).attributes || {}),
};
}
// Create resource with a construction compatible across OTel v1 and v2
const serviceName =
options.appName ||
process.env.OTEL_SERVICE_NAME ||
process.env.npm_package_name ||
"unknown-service";
const resource: Resource = new Resource({ [ATTR_SERVICE_NAME]: serviceName });
🤖 Prompt for AI Agents
In packages/traceloop-sdk/src/lib/tracing/index.ts around lines 310-339, the
current code calls resourceFromAttributes and on error re-invokes
resourceFromAttributes({}) and mutates resource.attributes; instead, build the
desired attributes up-front (serviceName = options.appName ||
process.env.OTEL_SERVICE_NAME || process.env.npm_package_name ||
"unknown-service"), call resourceFromAttributes exactly once with that
attributes object, remove the fallback that re-calls resourceFromAttributes, and
do not mutate the returned Resource; if resourceFromAttributes throws, log the
error and create a new Resource instance containing only the pre-computed
attributes (so you do not attempt to mutate internals or re-run the same failing
call) so NodeSDK can merge it with defaults.

Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed 8f95bd5 in 1 minute and 44 seconds. Click for details.
  • Reviewed 60 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/index.ts:337
  • Draft comment:
    Simplified fallback resource construction now directly calls resourceFromAttributes with the service name. Ensure that no essential default attributes are lost compared to the previous manual merge.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.

Workflow ID: wflow_FFloN6ogqZCTbPs0

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Comment thread packages/traceloop-sdk/src/lib/tracing/index.ts Outdated

try {
// Create our custom resource with service name and let NodeSDK handle default detection
resource = resourceFromAttributes({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider leveraging the newly imported detectResources (with envDetector and processDetector) to merge additional default resource attributes into your custom resource for enhanced resilience.

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: 0

♻️ Duplicate comments (1)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

316-344: Fallback retries the same failing path; construct Resource directly and respect OTEL_SERVICE_NAME

The catch block calls resourceFromAttributes again with the same args, so if the initial call throws (version mismatch, API differences), the fallback likely throws too and bubbles up. The extra shape checks are unnecessary for a typed Resource. Prefer constructing new Resource (works in OTel v1 and v2) and include process.env.OTEL_SERVICE_NAME in the resolution order.

Apply this diff:

-  // Create resource with proper detection and defensive handling for OTLP serialization
-  const serviceName =
-    options.appName || process.env.npm_package_name || "unknown-service";
-  let resource: Resource;
-
-  try {
-    // Create our custom resource with service name and let NodeSDK handle default detection
-    resource = resourceFromAttributes({
-      [ATTR_SERVICE_NAME]: serviceName,
-    });
-
-    // Defensive check to prevent OTLP serialization errors
-    if (!resource || typeof resource !== "object") {
-      throw new Error("Invalid resource object");
-    }
-
-    if (!resource.attributes || typeof resource.attributes !== "object") {
-      throw new Error("Resource missing attributes");
-    }
-  } catch (error) {
-    // Fallback: create a basic resource manually
-    diag.warn(
-      "Failed to create resource with resourceFromAttributes, using fallback",
-      error,
-    );
-    resource = resourceFromAttributes({
-      [ATTR_SERVICE_NAME]: serviceName,
-    });
-  }
+  // Create a minimal Resource compatible with OTel v1 and v2; NodeSDK will merge with detected defaults
+  const serviceName =
+    options.appName ||
+    process.env.OTEL_SERVICE_NAME ||
+    process.env.npm_package_name ||
+    "unknown-service";
+  const resource: Resource = new Resource({ [ATTR_SERVICE_NAME]: serviceName });
🧹 Nitpick comments (1)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

5-11: Simplify imports to the stable API used

With the above change, prefer importing only Resource from @opentelemetry/resources. This keeps the code lean and avoids reliance on helpers that complicate v1/v2 compatibility.

-import {
-  resourceFromAttributes,
-  Resource,
-  detectResources,
-  envDetector,
-  processDetector,
-} from "@opentelemetry/resources";
+import { Resource } from "@opentelemetry/resources";
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cf44602 and 8f95bd5.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/src/lib/tracing/index.ts (2 hunks)
🔇 Additional comments (1)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

347-347: LGTM: Passing the precomputed Resource into NodeSDK is correct

NodeSDK will merge this with its detected defaults, satisfying the PR’s goal to ensure a valid service.name without mutating internals.

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
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: 0

♻️ Duplicate comments (2)
packages/traceloop-sdk/src/lib/tracing/index.ts (2)

315-343: Avoid re-invoking the same failing path; use a stable fallback and honor OTEL_SERVICE_NAME

  • The catch block calls resourceFromAttributes again with the same input; if it failed once, it’s likely to fail again, defeating the “warn instead of throw” goal.
  • Add support for OTEL_SERVICE_NAME to align with OTel conventions.
  • Simplify/remove redundant defensive checks; NodeSDK accepts a Resource instance and merges defaults.

Apply this diff:

-  // Create resource with proper detection and defensive handling for OTLP serialization
-  const serviceName =
-    options.appName || process.env.npm_package_name || "unknown-service";
-  let resource: Resource;
-
-  try {
-    // Create our custom resource with service name and let NodeSDK handle default detection
-    resource = resourceFromAttributes({
-      [ATTR_SERVICE_NAME]: serviceName,
-    });
-
-    // Defensive check to prevent OTLP serialization errors
-    if (!resource || typeof resource !== "object") {
-      throw new Error("Invalid resource object");
-    }
-
-    if (!resource.attributes || typeof resource.attributes !== "object") {
-      throw new Error("Resource missing attributes");
-    }
-  } catch (error) {
-    // Fallback: create a basic resource manually
-    diag.warn(
-      "Failed to create resource with resourceFromAttributes, using fallback",
-      error,
-    );
-    resource = resourceFromAttributes({
-      [ATTR_SERVICE_NAME]: serviceName,
-    });
-  }
+  // Create resource with defensive handling and a stable fallback
+  const serviceName =
+    options.appName ||
+    process.env.OTEL_SERVICE_NAME ||
+    process.env.npm_package_name ||
+    "unknown-service";
+  let resource: Resource;
+
+  try {
+    resource = resourceFromAttributes({ [ATTR_SERVICE_NAME]: serviceName });
+  } catch (error) {
+    // Fallback: construct a plain Resource to avoid re-invoking the same failing path
+    diag.warn(
+      "Failed to create resource via resourceFromAttributes; falling back to bare Resource",
+      error,
+    );
+    resource = new Resource({ [ATTR_SERVICE_NAME]: serviceName });
+  }

5-10: Fix CI: remove unused imports (TS6133) to unblock the build

envDetector and processDetector are imported but never used, causing the pipeline failure.

Apply this diff:

 import {
-  resourceFromAttributes,
-  Resource,
-  envDetector,
-  processDetector,
+  resourceFromAttributes,
+  Resource,
 } from "@opentelemetry/resources";
🧹 Nitpick comments (1)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

315-315: Clarify comment or actually perform detection

The comment says “proper detection,” but detection isn’t performed here. Either adjust the comment or wire in detection elsewhere (NodeSDK can merge defaults).

Apply this diff (comment tweak):

-  // Create resource with proper detection and defensive handling for OTLP serialization
+  // Create resource with defensive handling for OTLP serialization; NodeSDK will merge defaults
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8f95bd5 and cbd1577.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/src/lib/tracing/index.ts (2 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
packages/traceloop-sdk/src/lib/tracing/index.ts

[error] 8-8: @rollup/plugin-typescript TS6133: 'envDetector' is declared but its value is never read. Build failed during 'nx run @traceloop/node-server-sdk:build' (rollup -c).

🔇 Additional comments (1)
packages/traceloop-sdk/src/lib/tracing/index.ts (1)

345-347: LGTM: Passing the precomputed Resource into NodeSDK is correct

This cleanly centralizes resource construction and lets NodeSDK merge in defaults.

Removes unused imports that were causing TypeScript build errors:
- envDetector from @opentelemetry/resources
- processDetector from @opentelemetry/resources

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed 42a627b in 42 seconds. Click for details.
  • Reviewed 13 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/index.ts:6
  • Draft comment:
    Removal of unused imports 'envDetector' and 'processDetector' improves code clarity. Ensure this removal is consistent with the updated behavior of resource creation in the SDK.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_0H3cHk8o8J2HuTem

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Fixes prettier formatting issues after removing unused imports.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed db16cd1 in 28 seconds. Click for details.
  • Reviewed 16 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/index.ts:2
  • Draft comment:
    Simplify multiline import to a single line for better readability; the change is stylistic and poses no functional risk.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_lxIVsds7YkroWPIi

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@nirga nirga merged commit 27bfaec into main Aug 15, 2025
4 of 5 checks passed
@nirga nirga deleted the gk/otel-version-conflict branch August 15, 2025 16:59
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.

2 participants