skill.name OTel attribute never populated for non-built-in skills under service.name=claude-code, even with a valid plugin manifest

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 30, 2026

Title

skill.name OTel attribute is never populated for non-built-in skills when running via the Claude Code CLI, even when the skill is installed through a plugin with a valid .claude-plugin/plugin.json

Summary

The skill.name attribute (documented at https://code.claude.com/docs/en/monitoring-usage, gated by OTEL_LOG_TOOL_DETAILS=1) never resolves to a real value for any non-built-in skill when telemetry is emitted with service.name = claude-code (the CLI) — it is either unset or collapsed to a generic third-party redaction bucket, even for a plugin with a confirmed-working manifest. Built-in/first-party skills (e.g. artifact-design) resolve correctly. This makes it impossible for an org to see which custom/third-party skill was actually used from claude-code-sourced telemetry.

Environment

  • CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_LOGS_EXPORTER=otlp (org-managed settings), OTEL_LOG_TOOL_DETAILS=1 set org-wide.
  • Telemetry destination: an internal Honeycomb environment, receiving OTLP export from Claude Code CLI sessions across the org.
  • (Please let us know if you need the exact claude --version used in a specific session — happy to pin down a precise repro version on request.)

Evidence

  1. Grouping all telemetry by skill.name and service.name over a 7-day window, within service.name = claude-code specifically:

| skill.name | count |
| --- | --- |
| (No value) | ~15,000+ |
| third-party | ~71–80 |
| claude-api | ~12–15 |
| artifact-design | ~2–5 |
| mcp-apps:add-app-to-server | 1 |

The only non-empty values that ever resolve to a real name are confirmed Anthropic-shipped built-ins (claude-api, artifact-design, mcp-apps:add-app-to-server). We can't rule out that most of the (No value) volume is simply telemetry unrelated to any skill invocation at all (plain prompts, tool calls, etc. where skill.name was never applicable) rather than skill invocations that lost even a categorical label. The unambiguous evidence is the third-party bucket: a specific, deliberately-emitted redaction value, never the real skill name, for every one of those ~71–80 records regardless of which skill was actually invoked.

  1. Filtering directly for a specific, actively-used custom skill by its exact frontmatter name: returns zero matching records under service.name = claude-code, despite confirmed real usage of that skill in that window.
  2. To rule out "the skill's plugin lacks a manifest" as the cause: we tested a third-party plugin that has a confirmed working .claude-plugin/plugin.json — proven by the fact that its plugin_loaded event correctly reports real plugin.name/marketplace.name values under service.name = claude-code. That plugin's own skill (frontmatter name: autoresearch) still returns zero results when filtering skill.name = autoresearch under service.name = claude-code, over the same window the plugin_loaded events for that same plugin are present.
  3. By contrast, telemetry with service.name = claude (a different product/client) resolves skill.name correctly and broadly for third-party/custom skills, including the exact one from point 3's underlying repo and several unrelated third-party skills. This suggests the schema/pipeline is capable of carrying this attribute correctly elsewhere, and the gap is specific to the Claude Code CLI client's own telemetry emission.

Why this matters

Orgs deploying Claude Code CLI with custom/marketplace skills have no way to attribute skill usage by name in their observability tooling — only built-in skill usage is visible. This blocks basic usage analytics (which custom skills are actually being used, by whom, how often) for any org relying on OTel/Honeycomb-style dashboards, and isn't documented as a limitation anywhere in the current monitoring-usage docs (which describe skill.name as gated only by OTEL_LOG_TOOL_DETAILS, with no mention of a built-in-only restriction).

Suggested fix / ask

  • Confirm whether this is intentional (e.g. a deliberate restriction to avoid unbounded cardinality from arbitrary skill names) or a bug.
  • If intentional, document the restriction explicitly in the monitoring-usage docs, since the current docs imply skill.name works for any skill once OTEL_LOG_TOOL_DETAILS=1 is set.
  • If a bug, requesting that skill.name populate for any skill Claude Code Ioads and invokes, not just first-party/built-in ones — this is the only piece missing to make custom skill usage observable from Claude Code CLI telemetry.

Related

  • #80948 investigates claude_code.plugin_loaded being dropped by a startup race (event logger not initialized before plugin load fires). That issue is about a different event/attribute pair (plugin.name/marketplace.name on plugin_loaded) and doesn't mention skill.name at all — this issue is about skill.name specifically, which lives on a different event/metric and is emitted at a different point in the session lifecycle (per invocation, not once at session start). The two may or may not share a root cause; noting the connection since both surfaced from the same investigation.
  • We previously filed https://github.com/anthropics/claude-code/issues/80340 (SHA-pinned git-subdir refs not resolvable by the plugin installer) from the same investigation thread — happy to provide further repro detail or a minimal test plugin if useful.

View original on GitHub ↗