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
- 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.
- Widen options.scope (or maxScope) in createKnowledgeWriteTools if the curator legitimately needs broader visibility.
- Verify the tenant coordinates (org/resource/thread) used to build options.scope match the data's origin.
- 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
- Only pass node/record IDs obtained from reads within the same scope.
- Keep maxScope consistent with the data's creation scopes.
- Never share entity IDs across tenants or environments.
- Log scope keys (knowledgeScopeKey) alongside IDs to ease debugging.
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
- Session is not available to the current user
- Factory session ${session.sessionId} is not available to the
- AGENT_MEMORY_THREAD_RESOURCE_MISMATCH
- Thread with id ${threadId} is for resource with id ${thread.
- Thread not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/24cc4d0694be6054.
Report an issue: GitHub.