{"record":{"id":"3158453a8be74112","repo":"mastra-ai/mastra","slug":"knowledge-scope-contains-multiple-level-entries","errorCode":null,"errorMessage":"Knowledge scope contains multiple ${level} entries","messagePattern":"Knowledge scope contains multiple (.+?) entries","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/knowledge/base.ts","lineNumber":287,"sourceCode":"}\n\nconst SCOPE_ORDER: Record<KnowledgeScopeLevel, number> = { org: 0, resource: 1, thread: 2 };\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\nlet lastUlidTime = -1;\nlet lastUlidRandom = 0n;\n\nexport function canonicalizeKnowledgeScope(scope: KnowledgeScope): KnowledgeScope {\n  const entriesByLevel = new Map<KnowledgeScopeLevel, string>();\n  for (const entry of scope) {\n    const separator = entry.indexOf(':');\n    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;","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/knowledge/base.ts#L269-L305","documentation":"A knowledge scope may contain at most one entry per level (one org, one resource, one thread). canonicalizeKnowledgeScope detects two distinct entries at the same level and throws this error; identical duplicate entries are silently deduplicated.","triggerScenarios":"Passing a scope like ['org:a', 'org:b'] or ['thread:t1', 'thread:t2'] to any knowledge API that canonicalizes scope (queryScope, resolveScope, knowledgeScopeKey, expandKnowledgeScope, node writes).","commonSituations":"Merging scope arrays collected from multiple sources (org config + user config) without deduplicating by level; accidental double-append of the same level with different ids; migrating code that previously treated scope as an arbitrary bag of namespaces.","solutions":["Deduplicate by level before calling: keep exactly one id per level (the narrowest intended one).","If two ids at the same level are genuinely different tenants/threads, this is a caller logic bug — pick the correct one or issue separate queries per scope.","Build scopes via a builder that overwrites per-level entries (last-wins) rather than concatenating arrays."],"exampleFix":"// before\nconst scope = [`org:${orgA}`, `org:${orgB}`, `resource:${r}`];\n// after\nconst scope = [`org:${orgA}`, `resource:${r}`]; // one entry per level","handlingStrategy":"validation","validationCode":"function dedupeScopeByLevel(scope: string[]): string[] {\n  const byLevel = new Map<string, string>();\n  for (const e of scope) byLevel.set(e.slice(0, e.indexOf(':')), e); // last-wins per level\n  return [...byLevel.values()];\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat KnowledgeScope as 'one entry per level', not an arbitrary list.","Merge scope sources with a per-level Map, never Array.concat.","Add a unit test asserting scopes your app builds have unique levels."],"tags":["knowledge","scope","validation","duplicate"],"backgroundTag":"invalid-scope-entry","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}