Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(kb): fix Linear connector GraphQL type errors and tag slot reuse (#…
…3961)

* fix(kb): fix Linear connector GraphQL type errors and tag slot reuse

* fix(kb): simplify tag slot reuse, revert Linear GraphQL types to String

Clean up newTagSlotMapping into direct assignment, remove unnecessary
comment, and revert ID! back to String! to match Linear SDK types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): use ID! type for Linear GraphQL filter variables

* fix(kb): verify field type when reusing existing tag slots

Add fieldType check to the tag slot reuse logic so a connector with
a matching displayName but different fieldType falls through to fresh
slot allocation instead of silently reusing an incompatible slot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): enable search on connector selector dropdowns

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
  • Loading branch information
waleedlatif1 and claude authored Apr 4, 2026
commit a70ccddef5b1187b115dd2e2836598384ad83e0c
26 changes: 23 additions & 3 deletions apps/sim/app/api/knowledge/[id]/connectors/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,39 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
}

const tagSlotMapping: Record<string, string> = {}
let newTagSlots: Record<string, string> = {}

if (connectorConfig.tagDefinitions?.length) {
const disabledIds = new Set((sourceConfig.disabledTagIds as string[] | undefined) ?? [])
const enabledDefs = connectorConfig.tagDefinitions.filter((td) => !disabledIds.has(td.id))

const existingDefs = await db
.select({ tagSlot: knowledgeBaseTagDefinitions.tagSlot })
.select({
tagSlot: knowledgeBaseTagDefinitions.tagSlot,
displayName: knowledgeBaseTagDefinitions.displayName,
fieldType: knowledgeBaseTagDefinitions.fieldType,
})
.from(knowledgeBaseTagDefinitions)
.where(eq(knowledgeBaseTagDefinitions.knowledgeBaseId, knowledgeBaseId))

const usedSlots = new Set<string>(existingDefs.map((d) => d.tagSlot))
const { mapping, skipped: skippedTags } = allocateTagSlots(enabledDefs, usedSlots)
const existingByName = new Map(
existingDefs.map((d) => [d.displayName, { tagSlot: d.tagSlot, fieldType: d.fieldType }])
)

const defsNeedingSlots: typeof enabledDefs = []
for (const td of enabledDefs) {
const existing = existingByName.get(td.displayName)
if (existing && existing.fieldType === td.fieldType) {
tagSlotMapping[td.id] = existing.tagSlot
} else {
defsNeedingSlots.push(td)
}
}

const { mapping, skipped: skippedTags } = allocateTagSlots(defsNeedingSlots, usedSlots)
Comment thread
waleedlatif1 marked this conversation as resolved.
Object.assign(tagSlotMapping, mapping)
newTagSlots = mapping

for (const name of skippedTags) {
logger.warn(`[${requestId}] No available slots for "${name}"`)
Expand Down Expand Up @@ -208,7 +228,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
throw new Error('Knowledge base not found')
}

for (const [semanticId, slot] of Object.entries(tagSlotMapping)) {
for (const [semanticId, slot] of Object.entries(newTagSlots)) {
const td = connectorConfig.tagDefinitions!.find((d) => d.id === semanticId)!
await createTagDefinition(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export function ConnectorSelectorField({
options={comboboxOptions}
value={value || undefined}
onChange={onChange}
searchable
searchPlaceholder={`Search ${field.title.toLowerCase()}...`}
placeholder={
!credentialId
? 'Connect an account first'
Expand Down
6 changes: 3 additions & 3 deletions apps/sim/connectors/linear/linear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const ISSUE_FIELDS = `
`

const ISSUE_BY_ID_QUERY = `
query GetIssue($id: String!) {
query GetIssue($id: ID!) {
issue(id: $id) {
${ISSUE_FIELDS}
}
Expand Down Expand Up @@ -147,13 +147,13 @@ function buildIssuesQuery(sourceConfig: Record<string, unknown>): {
const variables: Record<string, unknown> = {}

if (teamId) {
varDefs.push('$teamId: String!')
varDefs.push('$teamId: ID!')
filterClauses.push('team: { id: { eq: $teamId } }')
variables.teamId = teamId
}

if (projectId) {
varDefs.push('$projectId: String!')
varDefs.push('$projectId: ID!')
filterClauses.push('project: { id: { eq: $projectId } }')
variables.projectId = projectId
}
Expand Down