Skip to content

fix(skills): align description cap with the 1024-char Agent Skills spec - #1119

Merged
philmerrell merged 1 commit into
developfrom
feature/skill-description-char-limit
Sep 15, 2026
Merged

philmerrell merged 1 commit into
developfrom
feature/skill-description-char-limit

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

Problem

Creating a skill in the admin view rejects valid Anthropic-authored skills: the description field caps at 500 characters, but the Agent Skills spec allows 1,024:

description: Must be non-empty, Maximum 1,024 characters, Cannot contain XML tags

Our cap was roughly half the spec, so a skill that uses the upper half of its budget can't be imported. This isn't hypothetical — scanning the SKILL.md files available locally, these were blocked:

Skill Description length
math-olympiad (Anthropic official plugin) 704
cutting-a-release (this repo) 597
hook-development (Anthropic official plugin) 525
dotenv 518
kaizen-review-prep (this repo) 504

Two of our own .claude/skills/ couldn't be re-created through our own admin UI.

The field was also enforced at three different numbers for one column: 500 on the admin path, 2,000 on the user-authored path (CreateMySkillRequest), and no cap at all on the Skill record itself — so nothing about storage required 500. It was purely form validation, and the strictest of three.

Change

A single spec-derived constant, now the source for all four enforcement points.

BackendSKILL_DESCRIPTION_MAX_LENGTH = 1024 in apis/shared/skills/models.py, applied to:

  • SkillCreateRequest / SkillUpdateRequest (admin) — was 500
  • CreateMySkillRequest / UpdateMySkillRequest (user-authored) — was 2,000

Frontend — mirrored in shared/skills/skill-field-limits.ts, following the existing skill-resource-types.ts precedent of a documented client mirror naming the Python file as canonical. Used by both the admin and Customize skill forms. The admin form's error text now interpolates the constant instead of hardcoding "500", so the message can't drift from the validator again.

Why keep a cap at all: description is the Level-1 catalog line injected into the cacheable system prompt for every enabled skill, on every turn — exactly the kind of thing CLAUDE.md's cost tenet says to bound. This sets the right number rather than removing the bound.

Verification

  • Boundary, all four request models: 1,024 accepted, 1,025 rejected — checked directly against each.
  • Backend: 366 skill tests pass.
  • Frontend: 3,149 tests / 251 files pass; tsc --noEmit clean; AOT build clean (strictTemplates covers the new template binding).

No browser check: port 4200 was held by another session's dev server from a different checkout, so it would have exercised the wrong code.

Reviewer notes

Lowering the user-authored cap from 2,000 → 1,024 affects writes only. The Skill model has no read-side cap, so an existing longer record still loads and still works; it would fail only on a PUT that resends the description. I could not check live data for such records from this environment — worth a scan of the skills table for user-owned rows where length(description) > 1024 before this ships, if you want certainty.

Out of scope, noticed in passing: this repo's .claude/skills/kaizen-research has a 1,405-character description. That exceeds Anthropic's own 1,024 limit, so Claude Code's validation would reject it too — genuinely out of spec, not something our cap should accommodate.

🤖 Generated with Claude Code

The admin skill form capped `description` at 500 characters, rejecting
valid Anthropic-authored skills on import. The Agent Skills spec allows
1,024 — so the cap was roughly half the spec and blocked real skills
(`math-olympiad` at 704, `hook-development` at 525), including two of
this repo's own `.claude/skills/`.

The field was also enforced at three different numbers for one column:
500 on the admin path, 2,000 on the user-authored path, and no cap at
all on the `Skill` record itself. Replace all of them with a single
spec-derived constant.

A bound is still warranted — `description` is the Level-1 catalog line
injected into the cacheable system prompt for every enabled skill, on
every turn — so this sets the right number rather than removing the cap.

- Add `SKILL_DESCRIPTION_MAX_LENGTH = 1024` to `apis/shared/skills/models`
- Apply it to SkillCreate/Update (was 500) and CreateMy/UpdateMySkill
  (was 2,000)
- Mirror it client-side in `shared/skills/skill-field-limits.ts`, following
  the `skill-resource-types.ts` precedent, and use it in both skill forms
- Interpolate the constant into the admin form's error text so the message
  cannot drift from the validator again

Note: lowering the user-authored cap from 2,000 to 1,024 affects only
writes. The `Skill` model has no read-side cap, so an existing longer
record still loads; it would fail only on a PUT that resends the
description.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@philmerrell
philmerrell merged commit 0d89678 into develop Sep 15, 2026
6 checks passed
@philmerrell
philmerrell deleted the feature/skill-description-char-limit branch September 15, 2026 18: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.

1 participant