{"record":{"id":"79f6a8507d1743bb","repo":"siyuan-note/siyuan","slug":"capability-id-collision-s-s-and-s","errorCode":null,"errorMessage":"capability ID collision [%s]: %s and %s","messagePattern":"capability ID collision \\[(.+?)\\]: (.+?) and (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/capability.go","lineNumber":298,"sourceCode":"\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tsort.Slice(set.definitions, func(i, j int) bool {\n\t\treturn set.definitions[i].Function.Name < set.definitions[j].Function.Name\n\t})\n\treturn set, nil\n}\n\nfunc (set *capabilitySet) add(registration *capabilityRegistration) error {\n\tif set.registrations == nil {\n\t\tset.registrations = map[string]*capabilityRegistration{}\n\t}\n\tif set.ids == nil {\n\t\tset.ids = map[string]*capabilityRegistration{}\n\t}\n\tif previous := set.ids[registration.ID]; previous != nil {\n\t\treturn fmt.Errorf(\"capability ID collision [%s]: %s and %s\",\n\t\t\tregistration.ID, previous.ModelName, registration.ModelName)\n\t}\n\tif previous := set.registrations[registration.ModelName]; previous != nil {\n\t\treturn fmt.Errorf(\"capability model name collision [%s]: %s and %s\",\n\t\t\tregistration.ModelName, previous.ID, registration.ID)\n\t}\n\tset.ids[registration.ID] = registration\n\tset.registrations[registration.ModelName] = registration\n\tset.definitions = append(set.definitions, openai.Tool{\n\t\tType: openai.ToolTypeFunction,\n\t\tFunction: &openai.FunctionDefinition{\n\t\t\tName:        registration.ModelName,\n\t\t\tDescription: registration.Description,\n\t\t\tParameters:  convertSchema(registration.InputSchema),\n\t\t},\n\t})\n\treturn nil\n}","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/agent/capability.go#L280-L316","documentation":"The capability set's add method rejects a registration whose capability ID is already taken by an earlier registration. Both duplicate and original ModelNames are reported so the caller can see which two capabilities clash. IDs must be unique across all registered capabilities (native and plugin).","triggerScenarios":"Calling add (via buildCapabilitySet or direct registration) with two capabilities that both declare the same registration.ID, e.g. a plugin capability whose ID collides with a native one or another plugin instance.","commonSituations":"Two plugin versions or two plugins register the same 'plugin/frontend/<name>' ID; a config lists the same capability twice; a native tool ID was copied into a custom registration; renaming a tool but forgetting to change its ID.","solutions":["Read the error's second ID (previous.ModelName vs registration.ModelName) to identify the two conflicting capabilities","Rename the duplicate capability's ID so it is unique (keep the 'plugin/frontend/' prefix convention for plugin tools)","Remove the stale/duplicate registration from config or plugin manifest","If a plugin is at fault, update it to a version with unique IDs"],"exampleFix":"// before\ncap1.ID = \"plugin/frontend/search\"; cap2.ID = \"plugin/frontend/search\"\n// after\ncap2.ID = \"plugin/frontend/search2\"","handlingStrategy":"validation","validationCode":"seen := map[string]bool{}\nfor _, c := range capabilities { if seen[c.ID] { return fmt.Errorf(\"duplicate capability ID %s\", c.ID) }; seen[c.ID] = true }","typeGuard":null,"tryCatchPattern":"if err := set.Add(reg); err != nil { if strings.Contains(err.Error(), \"ID collision\") { log.Printf(\"skipping duplicate capability: %v\", err); return nil }; return err }","preventionTips":["Namespace capability IDs by plugin name and version","Add a uniqueness assertion in plugin manifest linting","Deduplicate capabilities before calling buildCapabilitySet"],"tags":["agent","capability","collision","registration"],"backgroundTag":"conflicting-config-options","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}