@@ -3,6 +3,7 @@ import { document, embedding, knowledgeBase, knowledgeConnector } from '@sim/db/
33import { createLogger } from '@sim/logger'
44import { chunkArray } from '@sim/utils/helpers'
55import { generateId } from '@sim/utils/id'
6+ import { truncate } from '@sim/utils/string'
67import { and , eq , exists , inArray , isNull , lt , or , sql } from 'drizzle-orm'
78import { getInternalApiBaseUrl } from '@/lib/core/utils/urls'
89import type { DbOrTx } from '@/lib/db/types'
@@ -173,6 +174,19 @@ export async function persistDocumentAcls(
173174
174175const MAX_SAFE_TITLE_LENGTH = 200
175176
177+ /**
178+ * A document's filename and text tags sit under btree indexes, and Postgres refuses an index
179+ * row past about 2.7 KB. A source title or tag value beyond that fails the row and, with it,
180+ * every sync that lists the document again. 512 characters keeps a four-byte-per-character
181+ * value inside the ceiling.
182+ */
183+ const MAX_INDEXED_TEXT_LENGTH = 512
184+
185+ /** Bounds a source-supplied value that lands in an indexed text column. */
186+ function boundIndexedText ( value : string ) : string {
187+ return truncate ( value , MAX_INDEXED_TEXT_LENGTH )
188+ }
189+
176190function sanitizeStorageTitle ( title : string ) : string {
177191 return title . replace ( / [ ^ a - z A - Z 0 - 9 . - ] / g, '_' ) . slice ( 0 , MAX_SAFE_TITLE_LENGTH )
178192}
@@ -250,7 +264,8 @@ export function resolveTagMapping(
250264 const result : Partial < DocumentTags > = { }
251265 for ( const [ semanticKey , slot ] of Object . entries ( mapping ) ) {
252266 const value = semanticTags [ semanticKey ]
253- ; ( result as Record < string , unknown > ) [ slot ] = value != null ? value : null
267+ ; ( result as Record < string , unknown > ) [ slot ] =
268+ typeof value === 'string' ? boundIndexedText ( value ) : value != null ? value : null
254269 }
255270 return result
256271}
@@ -278,7 +293,7 @@ function buildSkippedDocumentRow(
278293 return {
279294 id : generateId ( ) ,
280295 knowledgeBaseId,
281- filename : extDoc . title ,
296+ filename : boundIndexedText ( extDoc . title ) ,
282297 fileUrl : '' ,
283298 storageKey : null ,
284299 /** No artifact was stored; a provider's reported source size is not local storage usage. */
@@ -630,7 +645,7 @@ export async function addDocument(
630645 await tx . insert ( document ) . values ( {
631646 id : documentId ,
632647 knowledgeBaseId,
633- filename : extDoc . title ,
648+ filename : boundIndexedText ( extDoc . title ) ,
634649 fileUrl,
635650 storageKey : fileInfo . key ,
636651 fileSize : artifact . bytes . length ,
@@ -745,7 +760,7 @@ export async function updateDocument(
745760 await tx
746761 . update ( document )
747762 . set ( {
748- filename : extDoc . title ,
763+ filename : boundIndexedText ( extDoc . title ) ,
749764 fileUrl,
750765 storageKey : fileInfo . key ,
751766 fileSize : artifact . bytes . length ,
0 commit comments