{"record":{"id":"b1591002e70e27c2","repo":"mastra-ai/mastra","slug":"resource-knowledge-scope-requires-an-org-ancestor","errorCode":null,"errorMessage":"Resource knowledge scope requires an org ancestor","messagePattern":"Resource knowledge scope requires an org ancestor","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/knowledge/base.ts","lineNumber":298,"sourceCode":"    const level = entry.slice(0, separator) as KnowledgeScopeLevel;\n    const id = entry.slice(separator + 1);\n    if (separator <= 0 || !id || id.includes('\\u001f') || SCOPE_ORDER[level] === undefined) {\n      throw new Error(`Invalid knowledge scope entry: ${entry}`);\n    }\n    const existing = entriesByLevel.get(level);\n    if (existing && existing !== entry) {\n      throw new Error(`Knowledge scope contains multiple ${level} entries`);\n    }\n    entriesByLevel.set(level, entry);\n  }\n  if (entriesByLevel.size === 0) {\n    throw new Error('Knowledge scope cannot be empty');\n  }\n  if (entriesByLevel.has('thread') && (!entriesByLevel.has('resource') || !entriesByLevel.has('org'))) {\n    throw new Error('Thread knowledge scope requires resource and org ancestors');\n  }\n  if (entriesByLevel.has('resource') && !entriesByLevel.has('org')) {\n    throw new Error('Resource knowledge scope requires an org ancestor');\n  }\n\n  const unique = [...new Set(scope)];\n  unique.sort((a, b) => {\n    const aLevel = a.slice(0, a.indexOf(':')) as KnowledgeScopeLevel;\n    const bLevel = b.slice(0, b.indexOf(':')) as KnowledgeScopeLevel;\n    const aOrder = SCOPE_ORDER[aLevel] ?? Number.MAX_SAFE_INTEGER;\n    const bOrder = SCOPE_ORDER[bLevel] ?? Number.MAX_SAFE_INTEGER;\n    return aOrder - bOrder || a.localeCompare(b);\n  });\n  return unique;\n}\n\nexport function knowledgeScopeKey(scope: KnowledgeScope): string {\n  return canonicalizeKnowledgeScope(scope).join('\\u001f');\n}\n\nexport function isKnowledgeScopeVisible(recordScope: KnowledgeScope, queryScope: KnowledgeScope): boolean {","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/knowledge/base.ts#L280-L316","documentation":"A resource-scoped entry ('resource:<id>') requires its org ancestor ('org:<id>') in the same scope, since resources live under orgs. canonicalizeKnowledgeScope enforces this and throws when a resource entry appears without an org entry.","triggerScenarios":"Passing scope ['resource:r1'] or ['resource:r1', 'thread:t1'] without an org entry to any knowledge API that canonicalizes scope.","commonSituations":"Assuming the library can look up the org for a resource automatically (it cannot; scope must be self-contained); dropping the org entry during scope trimming; building scopes in services that only know the resource id.","solutions":["Include the org entry whenever a resource entry is present: ['org:<o>', 'resource:<r>'].","Store/resolve the owning orgId alongside resourceIds in your domain layer so scopes can always be composed completely.","Derive scopes via expandKnowledgeScope from a full context scope rather than assembling levels piecemeal."],"exampleFix":"// before\nconst scope = [`resource:${resourceId}`];\n// after\nconst scope = [`org:${orgId}`, `resource:${resourceId}`];","handlingStrategy":"validation","validationCode":"function requireOrgWithResource(scope: string[]): void {\n  const levels = new Set(scope.map(e => e.slice(0, e.indexOf(':'))));\n  if (levels.has('resource') && !levels.has('org')) {\n    throw new Error('Resource scope entry requires an org:<id> ancestor in the same scope');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store owning orgId alongside every resourceId in your domain model.","Compose scopes from a single resolver that always injects the org entry.","Review scope-trimming logic that may drop ancestors."],"tags":["knowledge","scope","hierarchy","validation"],"backgroundTag":"invalid-scope-entry","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}