{"record":{"id":"d89c88512b5938f5","repo":"supermemoryai/supermemory","slug":"supermemory-tools-config-accepts-either-projectid","errorCode":null,"errorMessage":"Supermemory tools config accepts either projectId or containerTags, not both.","messagePattern":"Supermemory tools config accepts either projectId or containerTags, not both\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tools/src/tools-shared.ts","lineNumber":67,"sourceCode":"\tlimit: 10,\n\tchunkThreshold: 0.6,\n} as const\n\n// Container tag constants\nexport const CONTAINER_TAG_CONSTANTS = {\n\tprojectPrefix: \"sm_project_\",\n\tdefaultTags: [\"sm_project_default\"] as string[],\n} as const\n\n/**\n * Helper function to generate container tags based on config\n */\nexport function getContainerTags(config?: {\n\tprojectId?: string\n\tcontainerTags?: string[]\n}): string[] {\n\tif (config?.projectId !== undefined && config.containerTags !== undefined) {\n\t\tthrow new Error(\n\t\t\t\"Supermemory tools config accepts either projectId or containerTags, not both.\",\n\t\t)\n\t}\n\tif (config?.projectId) {\n\t\treturn [`${CONTAINER_TAG_CONSTANTS.projectPrefix}${config.projectId}`]\n\t}\n\treturn config?.containerTags ?? CONTAINER_TAG_CONSTANTS.defaultTags\n}\n\n/**\n * Memory item interface representing a single memory with optional metadata\n */\nexport interface MemoryItem {\n\tmemory: string\n\tmetadata?: Record<string, unknown>\n}\n\n/**","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/supermemoryai/supermemory/blob/d436792e777a99865939dd543c8d1a16d57f54ec/packages/tools/src/tools-shared.ts#L49-L85","documentation":"getContainerTags enforces mutually exclusive configuration: you may scope Supermemory tools by projectId OR by an explicit containerTags array, never both, because projectId is just sugar for a project-prefixed container tag and mixing them is ambiguous.","triggerScenarios":"Passing a tools config like { projectId: 'p1', containerTags: ['user-1'] } to Supermemory tools that accept both fields.","commonSituations":"Migrating from containerTags to projectId and leaving the old field in the config; merging default config objects that each set a different field.","solutions":["Remove one of the two fields — prefer projectId for project scoping","If merging configs, delete containerTags when projectId is set","Add a type helper (Exact or a guard) so TS rejects both fields at compile time"],"exampleFix":"// before\nconst config = { projectId: 'p1', containerTags: ['user-1'] }\n\n// after\nconst config = { projectId: 'p1' }","handlingStrategy":"validation","validationCode":"if (config.projectId !== undefined && config.containerTags !== undefined) throw new TypeError('pass either projectId or containerTags')","typeGuard":"type ToolsConfig = { projectId: string; containerTags?: undefined } | { projectId?: undefined; containerTags: string[] }","tryCatchPattern":null,"preventionTips":["Use a discriminated union type so TS rejects both fields","Delete legacy containerTags when adopting projectId"],"tags":["validation","configuration","mutually-exclusive","supermemory"],"backgroundTag":"conflicting-options","analyzedSha":"d436792e777a99865939dd543c8d1a16d57f54ec","analyzedAt":"2026-08-28T18:04:46.947Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}