Skip to content

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

Description

@jariy17

Description

agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

Steps to Reproduce

  1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
  2. agentcore deploy
  3. Invoke the deployed agent so it produces LLM/tool calls
  4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

Also observable statically, without deploying:

  • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
  • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

Expected Behavior

TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

Actual Behavior

No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

constenableOtel=!isMcp&&config.language!=='TypeScript';

2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

CMD ["npx", "tsx", "main.ts"]

Compare src/assets/container/python/Dockerfile:40-44, which does branch:

{{#if enableOtel}}
CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
{{else}}
CMD ["python", "-m", "{{entrypoint}}"]
{{/if}}

Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

Origin of the regression

Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

  • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
  • removed import './otel-register.js'; from both main.ts files
  • removed 7 @opentelemetry/* dependencies from both package.json files
  • flipped schema-mapper.ts to exclude TypeScript

The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

Interaction with #1270 (important)

Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

Suggested fix

ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

Touch points:

  • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
  • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
  • both TS template package.json files — add the ADOT distro dependency
  • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
  • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

CLI Version

0.25.0 (repo package.json, at commit 8fba816)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
      Skip to content

      bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

      Description

      @jariy17

      Description

      agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

      This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

      Steps to Reproduce

      1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
      2. agentcore deploy
      3. Invoke the deployed agent so it produces LLM/tool calls
      4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

      Also observable statically, without deploying:

      • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
      • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

      Expected Behavior

      TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

      Actual Behavior

      No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

      1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

      constenableOtel=!isMcp&&config.language!=='TypeScript';

      2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

      CMD ["npx", "tsx", "main.ts"]

      Compare src/assets/container/python/Dockerfile:40-44, which does branch:

      {{#if enableOtel}}
      CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
      {{else}}
      CMD ["python", "-m", "{{entrypoint}}"]
      {{/if}}

      Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

      3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

      The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

      Origin of the regression

      Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

      • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
      • removed import './otel-register.js'; from both main.ts files
      • removed 7 @opentelemetry/* dependencies from both package.json files
      • flipped schema-mapper.ts to exclude TypeScript

      The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

      Interaction with #1270 (important)

      Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

      These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

      Suggested fix

      ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

      Touch points:

      • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
      • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
      • both TS template package.json files — add the ADOT distro dependency
      • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
      • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

      CLI Version

      0.25.0 (repo package.json, at commit 8fba816)

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
          Skip to content

          bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

          Description

          @jariy17

          Description

          agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

          This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

          Steps to Reproduce

          1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
          2. agentcore deploy
          3. Invoke the deployed agent so it produces LLM/tool calls
          4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

          Also observable statically, without deploying:

          • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
          • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

          Expected Behavior

          TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

          Actual Behavior

          No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

          1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

          constenableOtel=!isMcp&&config.language!=='TypeScript';

          2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

          CMD ["npx", "tsx", "main.ts"]

          Compare src/assets/container/python/Dockerfile:40-44, which does branch:

          {{#if enableOtel}}
          CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
          {{else}}
          CMD ["python", "-m", "{{entrypoint}}"]
          {{/if}}

          Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

          3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

          The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

          Origin of the regression

          Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

          • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
          • removed import './otel-register.js'; from both main.ts files
          • removed 7 @opentelemetry/* dependencies from both package.json files
          • flipped schema-mapper.ts to exclude TypeScript

          The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

          Interaction with #1270 (important)

          Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

          These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

          Suggested fix

          ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

          Touch points:

          • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
          • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
          • both TS template package.json files — add the ADOT distro dependency
          • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
          • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

          CLI Version

          0.25.0 (repo package.json, at commit 8fba816)

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
              Skip to content

              bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

              Description

              @jariy17

              Description

              agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

              This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

              Steps to Reproduce

              1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
              2. agentcore deploy
              3. Invoke the deployed agent so it produces LLM/tool calls
              4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

              Also observable statically, without deploying:

              • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
              • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

              Expected Behavior

              TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

              Actual Behavior

              No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

              1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

              constenableOtel=!isMcp&&config.language!=='TypeScript';

              2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

              CMD ["npx", "tsx", "main.ts"]

              Compare src/assets/container/python/Dockerfile:40-44, which does branch:

              {{#if enableOtel}}
              CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
              {{else}}
              CMD ["python", "-m", "{{entrypoint}}"]
              {{/if}}

              Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

              3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

              The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

              Origin of the regression

              Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

              • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
              • removed import './otel-register.js'; from both main.ts files
              • removed 7 @opentelemetry/* dependencies from both package.json files
              • flipped schema-mapper.ts to exclude TypeScript

              The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

              Interaction with #1270 (important)

              Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

              These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

              Suggested fix

              ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

              Touch points:

              • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
              • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
              • both TS template package.json files — add the ADOT distro dependency
              • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
              • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

              CLI Version

              0.25.0 (repo package.json, at commit 8fba816)

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
                  Skip to content

                  bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

                  Description

                  @jariy17

                  Description

                  agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

                  This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

                  Steps to Reproduce

                  1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
                  2. agentcore deploy
                  3. Invoke the deployed agent so it produces LLM/tool calls
                  4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

                  Also observable statically, without deploying:

                  • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
                  • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

                  Expected Behavior

                  TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

                  Actual Behavior

                  No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

                  1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

                  constenableOtel=!isMcp&&config.language!=='TypeScript';

                  2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

                  CMD ["npx", "tsx", "main.ts"]

                  Compare src/assets/container/python/Dockerfile:40-44, which does branch:

                  {{#if enableOtel}}
                  CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
                  {{else}}
                  CMD ["python", "-m", "{{entrypoint}}"]
                  {{/if}}

                  Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

                  3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

                  The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

                  Origin of the regression

                  Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

                  • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
                  • removed import './otel-register.js'; from both main.ts files
                  • removed 7 @opentelemetry/* dependencies from both package.json files
                  • flipped schema-mapper.ts to exclude TypeScript

                  The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

                  Interaction with #1270 (important)

                  Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

                  These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

                  Suggested fix

                  ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

                  Touch points:

                  • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
                  • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
                  • both TS template package.json files — add the ADOT distro dependency
                  • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
                  • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

                  CLI Version

                  0.25.0 (repo package.json, at commit 8fba816)

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
                      Skip to content

                      bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

                      Description

                      @jariy17

                      Description

                      agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

                      This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

                      Steps to Reproduce

                      1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
                      2. agentcore deploy
                      3. Invoke the deployed agent so it produces LLM/tool calls
                      4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

                      Also observable statically, without deploying:

                      • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
                      • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

                      Expected Behavior

                      TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

                      Actual Behavior

                      No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

                      1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

                      constenableOtel=!isMcp&&config.language!=='TypeScript';

                      2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

                      CMD ["npx", "tsx", "main.ts"]

                      Compare src/assets/container/python/Dockerfile:40-44, which does branch:

                      {{#if enableOtel}}
                      CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
                      {{else}}
                      CMD ["python", "-m", "{{entrypoint}}"]
                      {{/if}}

                      Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

                      3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

                      The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

                      Origin of the regression

                      Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

                      • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
                      • removed import './otel-register.js'; from both main.ts files
                      • removed 7 @opentelemetry/* dependencies from both package.json files
                      • flipped schema-mapper.ts to exclude TypeScript

                      The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

                      Interaction with #1270 (important)

                      Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

                      These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

                      Suggested fix

                      ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

                      Touch points:

                      • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
                      • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
                      • both TS template package.json files — add the ADOT distro dependency
                      • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
                      • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

                      CLI Version

                      0.25.0 (repo package.json, at commit 8fba816)

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
                          Skip to content

                          bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

                          Description

                          @jariy17

                          Description

                          agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

                          This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

                          Steps to Reproduce

                          1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
                          2. agentcore deploy
                          3. Invoke the deployed agent so it produces LLM/tool calls
                          4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

                          Also observable statically, without deploying:

                          • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
                          • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

                          Expected Behavior

                          TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

                          Actual Behavior

                          No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

                          1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

                          constenableOtel=!isMcp&&config.language!=='TypeScript';

                          2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

                          CMD ["npx", "tsx", "main.ts"]

                          Compare src/assets/container/python/Dockerfile:40-44, which does branch:

                          {{#if enableOtel}}
                          CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
                          {{else}}
                          CMD ["python", "-m", "{{entrypoint}}"]
                          {{/if}}

                          Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

                          3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

                          The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

                          Origin of the regression

                          Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

                          • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
                          • removed import './otel-register.js'; from both main.ts files
                          • removed 7 @opentelemetry/* dependencies from both package.json files
                          • flipped schema-mapper.ts to exclude TypeScript

                          The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

                          Interaction with #1270 (important)

                          Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

                          These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

                          Suggested fix

                          ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

                          Touch points:

                          • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
                          • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
                          • both TS template package.json files — add the ADOT distro dependency
                          • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
                          • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

                          CLI Version

                          0.25.0 (repo package.json, at commit 8fba816)

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry · Issue #1892 · aws/agentcore-cli · GitHub
                              Skip to content

                              bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry #1892

                              Description

                              @jariy17

                              Description

                              agentcore deploy does not set up any OpenTelemetry / ADOT instrumentation for TypeScript agents. Python agents get zero-code instrumentation via opentelemetry-instrument; TypeScript agents get nothing at any layer. As a result, spans emitted by any 3p instrumentation library (Strands, Vercel AI SDK, or a user's own @opentelemetry/api calls) are silently dropped, and nothing appears in CloudWatch / X-Ray Transaction Search.

                              This is a regression, not a never-implemented feature — the wiring existed and was removed (see below).

                              Steps to Reproduce

                              1. agentcore create --language TypeScript --sdk Strands --protocol HTTP --build Container
                              2. agentcore deploy
                              3. Invoke the deployed agent so it produces LLM/tool calls
                              4. Open CloudWatch → Application Signals / X-Ray Transaction Search and look for traces from the agent

                              Also observable statically, without deploying:

                              • Generated Dockerfile ends in CMD ["npx", "tsx", "main.ts"] — no instrumentation wrapper
                              • Generated package.json contains no OTel SDK, only the no-op @opentelemetry/api

                              Expected Behavior

                              TypeScript agents get zero-code ADOT instrumentation at parity with Python, so that 3p instrumentation libraries emitting via @opentelemetry/api export to the collector and show up in CloudWatch without any application code changes.

                              Actual Behavior

                              No instrumentation is configured. Three independent gaps, each sufficient on its own to produce zero telemetry:

                              1. enableOtel is hardcoded off for TypeScriptsrc/cli/operations/agent/generate/schema-mapper.ts:284

                              constenableOtel=!isMcp&&config.language!=='TypeScript';

                              2. The TypeScript Dockerfile has no instrumentation branch at allsrc/assets/container/typescript/Dockerfile:25

                              CMD ["npx", "tsx", "main.ts"]

                              Compare src/assets/container/python/Dockerfile:40-44, which does branch:

                              {{#if enableOtel}}
                              CMD ["opentelemetry-instrument", "python", "-m", "{{entrypoint}}"]
                              {{else}}
                              CMD ["python", "-m", "{{entrypoint}}"]
                              {{/if}}

                              Because no {{#if enableOtel}} block exists in the TS Dockerfile, setting instrumentation.enableOtel: true on a TypeScript agent has no effect — there is nothing for it to render. The schema at src/schema/schemas/agent-env.ts:194 defaults it to true and documents it as "the runtime entrypoint is wrapped with opentelemetry-instrument", which is silently untrue for TypeScript.

                              3. No OTel SDK dependency or bootstrap in the TS templates.src/assets/typescript/http/strands/base/package.json carries only @opentelemetry/api — the no-op API surface, which discards all spans unless a global provider is registered. src/assets/typescript/http/vercelai/base/package.json has no OTel dependency at all. Neither template registers a provider.

                              The CodeZip path is affected too: TS CodeZip builds are bundled with esbuild (src/lib/packaging/node.ts:95) and have no Dockerfile to hook, so they need the instrumentation applied via runtime env vars rather than a CMD change.

                              Origin of the regression

                              Commit 580cd10b"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 (2026-05-14) — removed the working implementation:

                              • deleted src/assets/typescript/http/strands/base/otel-register.ts and the vercelai equivalent, which registered a NodeTracerProvider + MeterProvider with OTLP exporters
                              • removed import './otel-register.js'; from both main.ts files
                              • removed 7 @opentelemetry/* dependencies from both package.json files
                              • flipped schema-mapper.ts to exclude TypeScript

                              The OTel removal was one commit inside a broader TS template/streaming PR, so it isn't visible from the PR title.

                              Interaction with #1270 (important)

                              Fixing the CLI alone is not sufficient to get traces into CloudWatch. Per #1270, AgentCore Runtime starts the ADOT collector sidecar on localhost:4318 only when it detects opentelemetry-instrument in the container entrypoint, which is Python-specific. A TypeScript entrypoint never matches, so nothing listens on :4318 and OTLP export fails silently even with a correctly registered SDK.

                              These two need to land together for end-to-end telemetry. Adopting a --require-based ADOT entrypoint (below) may also give the Runtime a detectable signal for starting the sidecar, which is worth confirming with the Runtime team.

                              Suggested fix

                              ADOT for Node exists and is current: @aws/aws-distro-opentelemetry-node-autoinstrumentation@0.12.0. True zero-code parity with Python is a NODE_OPTIONS=--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register entrypoint — a single dependency and no hand-maintained otel-register.ts, unlike the reverted implementation.

                              Touch points:

                              • src/cli/operations/agent/generate/schema-mapper.ts:284 — stop excluding TypeScript
                              • src/assets/container/typescript/Dockerfile — add the {{#if enableOtel}} branch
                              • both TS template package.json files — add the ADOT distro dependency
                              • TS CodeZip path — set the instrumentation env vars on the runtime (no Dockerfile to hook)
                              • src/assets/__tests__/dockerfile-render.test.ts — currently only exercises the Python Dockerfile; add TS coverage so this cannot silently regress again

                              CLI Version

                              0.25.0 (repo package.json, at commit 8fba816)

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions