{"record":{"id":"8d41efef03cf5d45","repo":"mastra-ai/mastra","slug":"invalid-knowledge-scope-entry-entry","errorCode":null,"errorMessage":"Invalid knowledge scope entry: ${entry}","messagePattern":"Invalid knowledge scope entry: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/knowledge/base.ts","lineNumber":283,"sourceCode":"  constructor(type: string, id: string) {\n    super(`Knowledge ${type} not found: ${id}`);\n    this.name = 'KnowledgeNotFoundError';\n  }\n}\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)];","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/knowledge/base.ts#L265-L301","documentation":"canonicalizeKnowledgeScope validates every scope entry string, which must have the form '<level>:<id>' where level is one of 'org', 'resource', or 'thread', and the id must be non-empty and must not contain the \\u001f unit-separator character (used internally to join scope keys). An entry failing shape or level validation throws this error before any knowledge operation runs.","triggerScenarios":"Passing a scope array containing e.g. 'resource' (no colon), ':abc' (empty level), 'org:' (empty id), 'tenant:123' (unknown level), 'org:a\\u001fb', or a non-string/undefined value coerced into the array, to any API accepting a KnowledgeScope (createNode, appendKnowledge, search, listNodes, queryScope, resolveScope, expandKnowledgeScope, knowledgeScopeKey).","commonSituations":"Building scope strings with template literals where an id variable is empty/undefined; using a custom scope vocabulary from an older API version; concatenating scope arrays with plain ids not yet prefixed with a level; ids containing control characters from copy-pasted data.","solutions":["Ensure every entry is '<level>:<id>' with level in {org, resource, thread} and a non-empty id.","Strip or reject ids containing the \\u001f control character before calling the API.","Centralize scope construction in a helper that validates entries once instead of scattering template literals.","Log the offending scope array; the thrown message includes the exact invalid entry."],"exampleFix":"// before\nconst scope = [resourceId]; // 'abc'\n// after\nconst scope = [`resource:${resourceId}`]; // 'resource:abc'","handlingStrategy":"validation","validationCode":"const LEVELS = ['org', 'resource', 'thread'];\nfunction isValidScopeEntry(entry: unknown): entry is string {\n  if (typeof entry !== 'string') return false;\n  const i = entry.indexOf(':');\n  if (i <= 0) return false;\n  const id = entry.slice(i + 1);\n  return id.length > 0 && !id.includes('\\u001f') && LEVELS.includes(entry.slice(0, i));\n}\n// assert scope.every(isValidScopeEntry) before calling knowledge APIs","typeGuard":"function isKnowledgeScope(v: unknown): v is string[] {\n  return Array.isArray(v) && v.length > 0 && v.every(isValidScopeEntry);\n}","tryCatchPattern":null,"preventionTips":["Build scope entries only through a helper like makeScopeEntry(level, id).","Validate scope arrays at configuration/tenant resolution time, before any knowledge call.","Sanitize ids for control characters (notably \\u001f) at ingestion boundaries."],"tags":["knowledge","scope","validation","input-format"],"backgroundTag":"invalid-scope-entry","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}