How Hidden Unicode Characters Are Handled in Claude Plugin Names and Descriptions

All name and description fields in Claude plugins are validated against the I10 invariant, which explicitly rejects zero-width spaces, byte-order-marks (BOM), and bidirectional control characters.

When submitting a plugin to the Claude marketplace, hidden Unicode characters in metadata fields trigger an immediate validation failure. This security-focused approach prevents invisible text manipulation and ensures transparent plugin identification across all rendering contexts.

The I10 Invariant Validation

The I10 invariant enforces strict Unicode hygiene on plugin metadata. As implemented in anthropics/claude-plugins-community, this check scans both the name and description fields for invisible characters that could obscure a plugin's true identity or interfere with text processing pipelines.

The validation fails with this specific message when hidden characters are detected:


I10: name/description contains hidden-Unicode (zero-width or bidi control)

No automatic sanitization occurs—authors must manually remove offending characters and resubmit. This explicit failure pattern ensures developers understand and fix the root cause rather than relying on silent cleanup.

Files and Implementation

Two key locations define this behavior:

File Purpose
.github/actions/validate-plugins/README.md Documents invariant I10 requirements
.github/actions/validate-plugins/scripts/11-validate-invariants.sh Executes the Unicode validation check

The shell script 11-validate-invariants.sh runs as part of the CI pipeline for every plugin submission, applying the same Unicode detection logic across all marketplace entries.

Detecting Hidden Unicode Characters Locally

Developers can replicate the I10 check before submission using either Python or shell tools.

Python Detection Method

This regex-based approach matches the character ranges used in the official validator:

import re

HIDDEN_UNICODE_RE = re.compile(
    r'[\u200B-\u200D\uFEFF\u2060\u180E]'   # zero-width spaces, BOM, word-joiner

    r'|[\u202A-\u202E]'                    # bidirectional controls

)

def contains_hidden(text: str) -> bool:
    return bool(HIDDEN_UNICODE_RE.search(text))

# Test cases

name = "My Plugin"            # contains zero-width space (U+2009)

desc = "A useful tool."

print(contains_hidden(name))   # → True

print(contains_hidden(desc))   # → False

Shell Detection Method

For CI integration or quick checks at the command line:

#!/usr/bin/env bash
hidden_check() {
  local text="$1"
  if printf '%s' "$text" | grep -P '[\x{200B}-\x{200D}\x{FEFF}\x{202A}-\x{202E}]' > /dev/null; then
    return 0   # hidden char found

  else
    return 1   # clean

  fi
}

name="Bad​Name"   # contains ZERO WIDTH SPACE (U+200B)

if hidden_check "$name"; then echo "⚠️ Hidden Unicode detected"; fi

Character Categories Blocked

The I10 invariant specifically targets three Unicode categories:

  • Zero-width spaces: U+200B (ZERO WIDTH SPACE), U+200C (ZERO WIDTH NON-JOINER), U+200D (ZERO WIDTH JOINER), U+2060 (WORD JOINER), U+180E (MONGOLIAN VOWEL SEPARATOR)
  • Byte-order-mark: U+FEFF (also functions as zero-width no-break space)
  • Bidirectional control characters: U+202A through U+202E (explicit directional embedding and override controls)

These characters remain invisible in most rendering contexts while potentially altering text processing behavior—making them unsuitable for plugin metadata where clarity and predictability are essential.

Summary

  • The I10 invariant in anthropics/claude-plugins-community validates all plugin name and description fields
  • Zero-width spaces, BOM, and bidi control characters trigger immediate rejection
  • Validation occurs in .github/actions/validate-plugins/scripts/11-validate-invariants.sh
  • No automatic stripping—authors must manually clean their metadata
  • Python and shell tools can replicate the check for local pre-submission validation

Frequently Asked Questions

What happens if my plugin name contains a zero-width space?

Your submission fails CI validation with the error I10: name/description contains hidden-Unicode (zero-width or bidi control). You must remove the character and resubmit—no automatic fix is applied.

Which Unicode characters are considered "hidden" in plugin validation?

The validator blocks zero-width spaces (U+200B-U+200D, U+2060, U+180E), byte-order-marks (U+FEFF), and bidirectional control characters (U+202A-U+202E). These characters are invisible in standard text rendering.

Where is the hidden Unicode check implemented in the repository?

The check lives in .github/actions/validate-plugins/scripts/11-validate-invariants.sh and is documented in .github/actions/validate-plugins/README.md. Both files are part of the GitHub Actions validation pipeline for the Claude plugins marketplace.

Can I automatically strip hidden characters instead of manually removing them?

The official validator does not support automatic stripping. The intentional design requires authors to consciously fix their metadata, preventing accidental submission of sanitized-but-unintended values and ensuring full awareness of the original encoding issue.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →