mastra-ai/mastra · error

No versions found for skill ${id}

Error message

No versions found for skill ${id}

What it means

When update() receives config-field changes, in-memory skills storage reads the latest version to use as the base for a new version. If the skill exists but has no versions recorded in the map, there is nothing to derive from, so it throws. This mirrors the filesystem variant but for in-memory state.

Source

Thrown at packages/core/src/storage/domains/skills/inmemory.ts:152

      ...existingConfig,
      ...(authorId !== undefined && { authorId }),
      ...(visibility !== undefined && { visibility }),
      ...(activeVersionId !== undefined && { activeVersionId }),
      ...(status !== undefined && { status: status as StorageSkillType['status'] }),
      updatedAt: new Date(),
    };

    // Auto-set status to 'published' when activeVersionId is set, only if status is not explicitly provided
    if (activeVersionId !== undefined && status === undefined) {
      updatedConfig.status = 'published';
    }

    // If config fields are being updated, create a new version
    if (hasConfigUpdate) {
      // Get the latest version to use as base
      const latestVersion = await this.getLatestVersion(id);
      if (!latestVersion) {
        throw new Error(`No versions found for skill ${id}`);
      }

      // Extract config from latest version
      const {
        id: _versionId,
        skillId: _skillId,
        versionNumber: _versionNumber,
        changedFields: _changedFields,
        changeMessage: _changeMessage,
        createdAt: _createdAt,
        ...latestConfig
      } = latestVersion;

      // Merge updates into latest config
      const newConfig = {
        ...latestConfig,
        ...configFields,
      };

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Recreate the skill through the normal create path so an initial version is written.
  2. Seed at least one version for the skill before applying config updates.
  3. Update only metadata fields (authorId, visibility, activeVersionId, status) which do not require a version base.
  4. Fix the bypassing code path so skill creation always writes an initial version.

Example fix

// before
await skillsStorage.update({ id: 'deploy', instructions: 'v2' }); // throws: no versions
// after
await skillsStorage.create({ skill: { id: 'deploy', instructions: 'v2', ...rest } }); // creates version 1
Defensive patterns

Strategy: validation

Validate before calling

const latest = await storage.getLatestVersion(id);
if (!latest) throw new Error(`skill ${id} has no versions; recreate via create()`);

Type guard

async function hasVersionHistory(storage: InMemorySkillsStorage, id: string): Promise<boolean> {
  return (await storage.getLatestVersion(id)) != null;
}

Try / catch

try {
  return await storage.update(input);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('No versions found for skill')) {
    // metadata-only fallback or recreate
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling update with config fields on a skill created without any version records (e.g. state populated directly into db.skills in tests); getLatestVersion returning undefined because versions were never seeded or were cleared.

Common situations: Tests that hand-craft skill entries without versions; clearing the versions map independently; code paths that create skill metadata bypassing the version-creation step.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/1a6628d7582485e1. Report an issue: GitHub.