mastra-ai/mastra · error · Error

Invalid knowledge scope entry: ${entry}

Error message

Invalid knowledge scope entry: ${entry}

What it means

canonicalizeKnowledgeScope validates every scope entry string, which must have the form '<level>:<id>' where level is one of 'org', 'resource', or 'thread', and the id must be non-empty and must not contain the \u001f unit-separator character (used internally to join scope keys). An entry failing shape or level validation throws this error before any knowledge operation runs.

Source

Thrown at packages/core/src/storage/domains/knowledge/base.ts:283

  constructor(type: string, id: string) {
    super(`Knowledge ${type} not found: ${id}`);
    this.name = 'KnowledgeNotFoundError';
  }
}

const SCOPE_ORDER: Record<KnowledgeScopeLevel, number> = { org: 0, resource: 1, thread: 2 };
const CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
let lastUlidTime = -1;
let lastUlidRandom = 0n;

export function canonicalizeKnowledgeScope(scope: KnowledgeScope): KnowledgeScope {
  const entriesByLevel = new Map<KnowledgeScopeLevel, string>();
  for (const entry of scope) {
    const separator = entry.indexOf(':');
    const level = entry.slice(0, separator) as KnowledgeScopeLevel;
    const id = entry.slice(separator + 1);
    if (separator <= 0 || !id || id.includes('\u001f') || SCOPE_ORDER[level] === undefined) {
      throw new Error(`Invalid knowledge scope entry: ${entry}`);
    }
    const existing = entriesByLevel.get(level);
    if (existing && existing !== entry) {
      throw new Error(`Knowledge scope contains multiple ${level} entries`);
    }
    entriesByLevel.set(level, entry);
  }
  if (entriesByLevel.size === 0) {
    throw new Error('Knowledge scope cannot be empty');
  }
  if (entriesByLevel.has('thread') && (!entriesByLevel.has('resource') || !entriesByLevel.has('org'))) {
    throw new Error('Thread knowledge scope requires resource and org ancestors');
  }
  if (entriesByLevel.has('resource') && !entriesByLevel.has('org')) {
    throw new Error('Resource knowledge scope requires an org ancestor');
  }

  const unique = [...new Set(scope)];

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure every entry is '<level>:<id>' with level in {org, resource, thread} and a non-empty id.
  2. Strip or reject ids containing the \u001f control character before calling the API.
  3. Centralize scope construction in a helper that validates entries once instead of scattering template literals.
  4. Log the offending scope array; the thrown message includes the exact invalid entry.

Example fix

// before
const scope = [resourceId]; // 'abc'
// after
const scope = [`resource:${resourceId}`]; // 'resource:abc'
Defensive patterns

Strategy: validation

Validate before calling

const LEVELS = ['org', 'resource', 'thread'];
function isValidScopeEntry(entry: unknown): entry is string {
  if (typeof entry !== 'string') return false;
  const i = entry.indexOf(':');
  if (i <= 0) return false;
  const id = entry.slice(i + 1);
  return id.length > 0 && !id.includes('\u001f') && LEVELS.includes(entry.slice(0, i));
}
// assert scope.every(isValidScopeEntry) before calling knowledge APIs

Type guard

function isKnowledgeScope(v: unknown): v is string[] {
  return Array.isArray(v) && v.length > 0 && v.every(isValidScopeEntry);
}

Prevention

When it happens

Trigger: Passing a scope array containing e.g. 'resource' (no colon), ':abc' (empty level), 'org:' (empty id), 'tenant:123' (unknown level), 'org:a\u001fb', or a non-string/undefined value coerced into the array, to any API accepting a KnowledgeScope (createNode, appendKnowledge, search, listNodes, queryScope, resolveScope, expandKnowledgeScope, knowledgeScopeKey).

Common situations: Building scope strings with template literals where an id variable is empty/undefined; using a custom scope vocabulary from an older API version; concatenating scope arrays with plain ids not yet prefixed with a level; ids containing control characters from copy-pasted data.

Related errors


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