{"record":{"id":"3f555edde0644dff","repo":"github/copilot-sdk","slug":"duplicate-factory-name-definition-meta-name","errorCode":null,"errorMessage":"Duplicate factory name \"${definition.meta.name}\". Factory names must be unique within a joinSession call.","messagePattern":"Duplicate factory name \"(.+?)\"\\. Factory names must be unique within a joinSession call\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodejs/src/session.ts","lineNumber":1447,"sourceCode":"    }\n\n    /**\n     * Registers factory closures and reverse-RPC handlers for this session.\n     *\n     * @param factories - Factory handles declared by the joining extension.\n     * @internal Called by the SDK when an extension joins a session.\n     */\n    registerFactories(factories?: FactoryHandle[]): void {\n        this.factories.clear();\n        if (!factories || factories.length === 0) {\n            delete this.clientSessionApis.factory;\n            return;\n        }\n\n        for (const handle of factories) {\n            const definition = getFactoryDefinition(handle);\n            if (this.factories.has(definition.meta.name)) {\n                throw new Error(\n                    `Duplicate factory name \"${definition.meta.name}\". Factory names must be unique within a joinSession call.`\n                );\n            }\n            this.factories.set(definition.meta.name, definition);\n        }\n\n        const self = this;\n        this.clientSessionApis.factory = {\n            async execute(params) {\n                const definition = self.factories.get(params.name);\n                if (!definition) {\n                    const message = `No factory registered with name \"${params.name}\"`;\n                    throw new ResponseError(ErrorCodes.InvalidParams, message, {\n                        code: \"factory_not_found\",\n                        name: params.name,\n                    });\n                }\n","sourceCodeStart":1429,"sourceCodeEnd":1465,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L1429-L1465","documentation":"During joinSession, each factory handle is resolved to a definition and stored in this.factories keyed by meta.name. Registering two factories with the same name within one joinSession call is ambiguous (which definition should serve the name?), so it throws before mutating further.","triggerScenarios":"Passing a factories array to joinSession containing two handles whose definitions share the same meta.name — duplicates from spreading lists, or a factory accidentally included twice.","commonSituations":"Combining [ ...baseFactories, ...baseFactories ] or shared defaults arrays; copying a factory and changing only its behavior, not meta.name; re-exporting the same definition under two variable names.","solutions":["Give each factory a unique meta.name before joining.","Deduplicate the factories array before passing it to joinSession.","If two entries are truly the same factory, remove one from the list."],"exampleFix":"// before\njoinSession({ factories: [loggerFactory, loggerFactory] });\n// after\njoinSession({ factories: [...new Map(defs.map((d) => [getFactoryDefinition(d).meta.name, d])).values()] });","handlingStrategy":"validation","validationCode":"const names = factories.map((f) => getFactoryDefinition(f).meta.name);\nconst dupes = names.filter((n, i) => names.indexOf(n) !== i);\nif (dupes.length) throw new Error(`Duplicate factory names: ${dupes.join(', ')}`);","typeGuard":null,"tryCatchPattern":"try { await joinSession({ factories }); } catch (e) { if (String(e.message).includes('Duplicate factory name')) console.error('Deduplicate factories by meta.name before joining'); else throw e; }","preventionTips":["Deduplicate factories by meta.name before every joinSession call.","When forking a factory definition, change meta.name too.","Avoid spreading the same factories array twice into the config."],"tags":["duplicate","factory","registration"],"backgroundTag":"duplicate-key","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}