mastra-ai/mastra · error · KnowledgeInspectorError
not-visible
not-visible
Error message
Knowledge record is not visible in the selected scope.
What it means
#assertVisible() is a narrowing assertion: a record must exist AND its stored scope (org/resource/thread) must be visible within the caller's requested scope, checked via isKnowledgeScopeVisible. If the record is missing or lives outside the selected scope level, it throws KnowledgeInspectorError 'not-visible' — an access-control boundary, not a crash bug.
Source
Thrown at mastracode/sdk/src/knowledge-inspector.ts:496
if (level === 'org') return [`org:${binding.ownerId}`];
const scope = [`org:${binding.ownerId}`, `resource:${binding.resourceId}`];
if (level === 'resource') return scope;
if (!binding.threadId) {
throw new KnowledgeInspectorError('unavailable', 'The active thread does not belong to this project.');
}
return [...scope, `thread:${binding.threadId}`];
}
async #assertStable(binding: Binding): Promise<void> {
const current = await this.#binding();
if (current.identityKey !== binding.identityKey || current.fingerprint !== binding.fingerprint) {
throw new KnowledgeInspectorError('stale-handle', 'Knowledge scope changed while the request was running.');
}
}
#assertVisible<T extends KnowledgeNode>(record: T | null, scope: KnowledgeScope): asserts record is T {
if (!record || !isKnowledgeScopeVisible(record.scope, scope)) {
throw new KnowledgeInspectorError('not-visible', 'Knowledge record is not visible in the selected scope.');
}
}
#recordSummary(
record: KnowledgeNode,
binding: Binding,
level: KnowledgeInspectorScopeLevel,
): KnowledgeInspectorNodeSummary {
const type: KnowledgeInspectorRecordType = 'node';
return {
handle: this.#mintHandle(binding, level, type, record.id),
type,
name: record.name,
kind: record.kind,
scope: scopeBadge(record.scope),
version: record.version,
updatedAt: record.updatedAt.toISOString(),
};View on GitHub (pinned to 75dd419e61)
Solutions
- Request a scope level that covers the record (e.g. use 'org' or 'resource' level for records not confined to the thread).
- Only use handles/cursors within the scope level they were minted at.
- Catch KnowledgeInspectorError 'not-visible' and treat it as an empty/filtered result rather than retrying.
Example fix
// before
const node = await inspector.getNode(handle, { level: 'thread' }); // record is resource-scoped
// after
const node = await inspector.getNode(handle, { level: 'resource' }); // scope covers record Defensive patterns
Strategy: type-guard
Validate before calling
function scopeCovers(level: 'org' | 'resource' | 'thread', recordScope: string[]): boolean {
if (level === 'org') return true;
if (level === 'resource') return recordScope.some(s => s.startsWith('resource:'));
return recordScope.some(s => s.startsWith('thread:'));
}
// check before requesting a record at a given level Type guard
function isVisibleRecord<T extends { scope: string[] }>(record: T | null | undefined, scope: string[]): record is T {
return record != null && record.scope.every(tag => scope.includes(tag) || scope.some(s => s.startsWith('org:') && tag.startsWith('org:')));
} Try / catch
try {
const node = await inspector.getNode(handle, { level });
} catch (e) {
if (e instanceof KnowledgeInspectorError && e.code === 'not-visible') {
return undefined; // treat as filtered-out, not an error
}
throw e;
} Prevention
- Only present records to users whose scope level matches how they were listed.
- Never reuse handles across different scope levels.
- Handle deleted records: treat not-visible as 'gone or restricted'.
When it happens
Trigger: Resolving a record by id or handle whose scope is broader/narrower than the requested level — e.g. asking for a thread-scoped record while bound to 'resource' level, or the record was deleted (null) so the assertion fails.
Common situations: Using a handle minted at one scope level with a request at another; reading a node that exists only in an org-wide scope while inspecting project scope; record deleted between listing and reading.
Related errors
- Session is not available to the current user
- Factory session ${session.sessionId} is not available to the
- stale-handle
- invalid-handle
- invalid-cursor
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/cb74b67904d3c6e9.
Report an issue: GitHub.