mastra-ai/mastra · error · Error

${label} is outside the curator's visible scope.

Error message

${label} is outside the curator's visible scope.

What it means

Curator write tools operate only on entities visible inside the curator's configured scope (options.scope, itself bounded by options.maxScope). requireVisible checks a node's or record's stored scope against that visibility window using isKnowledgeScopeVisible and throws a labeled error naming the entity ('Knowledge node', 'KnowledgeRecord', 'Knowledge merge source/target') when it falls outside. This enforces multi-tenant isolation: a curator must never mutate knowledge belonging to another org, resource, or thread.

Source

Thrown at packages/memory/src/processors/observational-memory/subconscious/knowledge-write-tools.ts:44

  defaultScope: KnowledgeScopeLevel;
  maxScope?: KnowledgeScopeLevel;
}

async function getStore(memory: KnowledgeWriteToolsMemory): Promise<KnowledgeStorage> {
  const store = await memory.storage.getStore('knowledge');
  if (!store) throw new Error('Knowledge write tools require a configured knowledge storage domain.');
  return store;
}

function resolveWriteScope(options: KnowledgeWriteToolsOptions, level?: KnowledgeScopeLevel): KnowledgeScope {
  const scope = expandKnowledgeScope(options.scope, level ?? options.defaultScope);
  assertKnowledgeScopeWithinCeiling(scope, options.maxScope);
  return scope;
}

function requireVisible(scope: KnowledgeScope, options: KnowledgeWriteToolsOptions, label: string): void {
  if (!isKnowledgeScopeVisible(scope, options.scope)) {
    throw new Error(`${label} is outside the curator's visible scope.`);
  }
}

export function createKnowledgeWriteTools(
  memory: KnowledgeWriteToolsMemory,
  options: KnowledgeWriteToolsOptions,
): Record<string, ToolAction<any, any, any>> {
  return {
    knowledge_append: createTool({
      id: 'knowledge_append',
      description: 'Append a scoped record to an existing node. Provenance and capture time are stamped by code.',
      inputSchema: {
        type: 'object',
        properties: {
          node: { type: 'string', minLength: 1 },
          text: { type: 'string', minLength: 1 },
          scope: scopeLevelSchema,
          when: { type: 'string' },

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use node/record IDs that were created within the curator's scope; re-resolve by name in the current scope instead of reusing foreign IDs.
  2. Widen options.scope (or maxScope) in createKnowledgeWriteTools if the curator legitimately needs broader visibility.
  3. Verify the tenant coordinates (org/resource/thread) used to build options.scope match the data's origin.
  4. Check isKnowledgeScopeVisibility semantics: visibility means the stored scope is at or below the curator's window at the same coordinates.

Example fix

// before
const tools = createKnowledgeWriteTools(memory, {
  scope: ['org:org_1', 'resource:r1', 'thread:t1'], // thread-scoped curator
  sourceThreadId: 't1', defaultScope: 'thread',
});
await tools.knowledge_append.execute({ node: 'org_level_node', text: 'x' }, {} as any); // throws
// after
createKnowledgeWriteTools(memory, {
  scope: ['org:org_1', 'resource:r1', 'thread:t1'],
  maxScope: 'org', // allow org-level visibility if intended
  sourceThreadId: 't1', defaultScope: 'org',
});
Defensive patterns

Strategy: try-catch

Validate before calling

import { isKnowledgeScopeVisible } from '@mastra/core/storage';
// before calling a write tool with a known entity scope:
if (!isKnowledgeScopeVisible(entityScope, curatorOptions.scope)) {
  throw new Error('Target entity is not visible to this curator.');
}

Try / catch

try {
  return await curatorTools.knowledge_append.execute(args, {} as any);
} catch (e) {
  if (e instanceof Error && e.message.includes("outside the curator's visible scope")) {
    return { success: false, reason: 'scope-violation', label: e.message.split(' ')[0] };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling knowledge_append/knowledge_update_node/knowledge_remove/etc. with a node or recordId whose stored scope key is broader or different from the curator's resolution scope — e.g. a thread-scoped curator trying to touch an org-level node, or an ID referencing another tenant's entity.

Common situations: Cross-tenant IDs leaked into prompts or copied between environments; curators instantiated with a narrow (thread/resource) scope but agents supplying org-scoped node IDs; scope ceiling (maxScope) lowered after records were created at higher levels.

Related errors


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