mastra-ai/mastra · error · HTTPException

Version with id ${to} not found for scorer ${scorerId}

Error message

Version with id ${to} not found for scorer ${scorerId}

What it means

Thrown when the `to` version exists but belongs to a different scorer definition than the `scorerId` in the request path. Like the `from` counterpart, it returns 404 to avoid cross-scorer version disclosure. No configuration is copied in this case.

Source

Thrown at packages/server/src/server/handlers/scorer-versions.ts:482

      const scorer = await scorerStore.getById(scorerId);
      assertStoredResourceScope(scorer, await getStoredResourceScope(mastra, requestContext));

      const fromVersion = await scorerStore.getVersion(from);
      if (!fromVersion) {
        throw new HTTPException(404, { message: `Version with id ${from} not found` });
      }
      if (fromVersion.scorerDefinitionId !== scorerId) {
        throw new HTTPException(404, {
          message: `Version with id ${from} not found for scorer ${scorerId}`,
        });
      }

      const toVersion = await scorerStore.getVersion(to);
      if (!toVersion) {
        throw new HTTPException(404, { message: `Version with id ${to} not found` });
      }
      if (toVersion.scorerDefinitionId !== scorerId) {
        throw new HTTPException(404, {
          message: `Version with id ${to} not found for scorer ${scorerId}`,
        });
      }

      const fromConfig = extractConfigFromVersion(
        fromVersion as unknown as Record<string, unknown>,
        SNAPSHOT_CONFIG_FIELDS,
      );
      const toConfig = extractConfigFromVersion(
        toVersion as unknown as Record<string, unknown>,
        SNAPSHOT_CONFIG_FIELDS,
      );

      const diffs = computeVersionDiffs(fromConfig, toConfig);

      return {
        diffs,
        fromVersion,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use a `to` version id that belongs to the scorer named in the URL.
  2. List versions for the target scorer and copy an id from that list.
  3. If the target scorer is different, update the scorerId path parameter to match the version's owner.

Example fix

// before
await copyConfig({ scorerId: 'scorer-a', from: aFrom, to: scorerBVersionId });
// after
const versionsA = await getScorerVersions('scorer-a');
await copyConfig({ scorerId: 'scorer-a', from: aFrom, to: versionsA[versionsA.length - 1].id });
Defensive patterns

Strategy: validation

Validate before calling

const versions = await getScorerVersions(scorerId);
if (!versions.some(v => v.id === toId)) throw new Error(`version ${toId} does not belong to scorer ${scorerId}`);

Try / catch

try {
  await copyScorerVersionConfig({ scorerId, from, to });
} catch (e) {
  if (e instanceof MastraClientError && e.status === 404 && /for scorer/.test(e.message)) {
    console.error(`'to' version ${to} belongs to a different scorer — select a target owned by ${scorerId}.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling copy-config with a `to` version id owned by another scorer while the path names a different scorerId.

Common situations: Swapping from/to ids between two scorers; reusing a payload template that references versions of a different scorer; multi-tenant setups where ids collide across tenants' storages.

Related errors


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