paperclipai/paperclip · error · CapabilityMockControlPlaneError

fixture_state_invalid

fixture_state_invalid

Error message

A skill with that name already exists

What it means

CapabilityMockControlPlaneError with code `fixture_state_invalid`, thrown when a create_skill command would add a skill whose slug already exists within the same company in the mock control-plane state. The adapter enforces per-company uniqueness of skill slugs, mirroring the real control plane's uniqueness constraint.

Solutions

  1. Use a unique skill name (and slug) not already present for that company in the mock state
  2. Reset or rebuild the mock control-plane state between test runs
  3. Check existing skills via the snapshot and pick a non-colliding slug
  4. If re-creating intentionally, delete the existing skill or use an update command instead

Example fix

// before
await applyCommand({ kind: "create_skill", name: "deploy", ... }); // second run collides
// after
const exists = adapter.snapshot().skills?.some(s => s.companyId === companyId && s.slug === "deploy");
if (!exists) await applyCommand({ kind: "create_skill", name: "deploy", ... });
Defensive patterns

Strategy: try-catch

Validate before calling

const slug = command.slug ?? command.name;
const exists = adapter.snapshot().skills?.some(s => s.companyId === run.companyId && s.slug === slug);
if (exists) throw new Error(`Skill slug '${slug}' already exists for company`);

Try / catch

try {
  await adapter.applyCommand(cmd);
} catch (e) {
  if (e instanceof CapabilityMockControlPlaneError && e.code === "fixture_state_invalid"
    && e.message.includes("already exists")) {
    cmd.name = `${cmd.name}-${Date.now()}`; // retry with unique slug
  } else throw e;
}

Prevention

When it happens

Trigger: applyCommand → #executeCommand for create_skill where `this.#state.skills` already contains a skill with the same companyId and the resolved slug (command.slug ?? command.name). Re-running the same fixture command without resetting state, or creating two skills whose names slugify identically.

Common situations: Replaying a fixture or test twice against the same adapter state; two skills named 'Deploy App' and 'deploy-app' colliding on slug; forgetting that slug defaults to name so the name check is effectively a slug check.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/92ae8b7ff89a6f44. Report an issue: GitHub.

Appendix: source

Thrown at packages/paperclip-runner/src/mock-core/capability-mock-control-plane-adapter.ts:729

      }
      case "create_skill": {
        requireText(command.name, "skill name");
        requireText(command.markdown, "skill markdown");
        const document = parseFrontmatterMarkdown(command.markdown);
        const validMetadata = validateSkillFrontmatter(document.frontmatter);
        if (!document.hasFrontmatter || !validMetadata || !document.body.trim()
          || document.frontmatter.name !== command.name
          || document.frontmatter.description !== command.description.trim()
          || (command.slug !== undefined && command.slug !== command.name)) {
          throw new CapabilityMockControlPlaneError(
            "invalid_skill_document",
            "Provide a complete SKILL.md with name and description matching the command inputs, a nonempty body, and slug equal to name when supplied",
          );
        }
        const slug = command.slug ?? command.name;
        const skills = this.#state.skills ??= [];
        if (skills.some(skill => skill.companyId === run.companyId && skill.slug === slug)) {
          throw new CapabilityMockControlPlaneError("fixture_state_invalid", "A skill with that name already exists");
        }
        const skill = { id: this.#id("skill"), companyId: run.companyId, name: command.name,
          slug, description: command.description.trim(), markdown: command.markdown, versionId: this.#id("skill-version") };
        skills.push(skill);
        entityRefs.push(`skill:${skill.id}`);
        break;
      }
      case "write_document": {
        requireText(command.key, "document key");
        requireText(command.title, "document title");
        const existing = this.#state.documents.find(
          (document) => document.taskId === task.id && document.key === command.key,
        );
        if (existing === undefined && command.baseRevisionId !== null) {
          throw new CapabilityMockControlPlaneError(
            "document_revision_conflict",
            "a new document must use a null base revision",
          );

View on GitHub (pinned to 3f1d897a7c)