{"record":{"id":"d5f2d87b68082ab6","repo":"FlowiseAI/Flowise","slug":"number-of-keys-keystrings-length-does-not-mat-d5f2d8","errorCode":null,"errorMessage":"Number of keys (${keyStrings.length}) does not match number of group_ids ${groupIds.length})","messagePattern":"Number of keys \\((.+?)\\) does not match number of group_ids (.+?)\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/recordmanager/PostgresRecordManager/PostgresRecordManager.ts","lineNumber":324,"sourceCode":"        const queryRunner = dataSource.createQueryRunner()\n        const tableName = this.sanitizeTableName(this.tableName)\n\n        const updatedAt = await this.getTime()\n        const { timeAtLeast, groupIds: _groupIds } = updateOptions ?? {}\n\n        if (timeAtLeast && updatedAt < timeAtLeast) {\n            throw new Error(`Time sync issue with database ${updatedAt} < ${timeAtLeast}`)\n        }\n\n        // Handle both new format (objects with uid and docId) and old format (strings)\n        const isNewFormat = keys.length > 0 && typeof keys[0] === 'object' && 'uid' in keys[0]\n        const keyStrings = isNewFormat ? (keys as Array<{ uid: string; docId: string }>).map((k) => k.uid) : (keys as string[])\n        const docIds = isNewFormat ? (keys as Array<{ uid: string; docId: string }>).map((k) => k.docId) : keys.map(() => null)\n\n        const groupIds = _groupIds ?? keyStrings.map(() => null)\n\n        if (groupIds.length !== keyStrings.length) {\n            throw new Error(`Number of keys (${keyStrings.length}) does not match number of group_ids ${groupIds.length})`)\n        }\n\n        const recordsToUpsert = keyStrings.map((key, i) => [key, this.namespace, updatedAt, groupIds[i], docIds[i]])\n\n        const valuesPlaceholders = recordsToUpsert.map((_, j) => this.generatePlaceholderForRowAt(j, recordsToUpsert[0].length)).join(', ')\n\n        const query = `INSERT INTO \"${tableName}\" (key, namespace, updated_at, group_id, doc_id) VALUES ${valuesPlaceholders} ON CONFLICT (key, namespace) DO UPDATE SET updated_at = EXCLUDED.updated_at, doc_id = EXCLUDED.doc_id;`\n        try {\n            await queryRunner.manager.query(query, recordsToUpsert.flat())\n            await queryRunner.release()\n        } catch (error) {\n            console.error('Error updating in PostgresRecordManager:')\n            throw error\n        } finally {\n            await dataSource.destroy()\n        }\n    }\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/recordmanager/PostgresRecordManager/PostgresRecordManager.ts#L306-L342","documentation":"Postgres analog of error 264. Thrown in PostgresRecordManager.update when the resolved groupIds array length differs from keyStrings length. The Postgres upsert builds one placeholder row per key and zips groupIds positionally, so a length mismatch would misalign rows.","triggerScenarios":"updateOptions.groupIds supplied with a different length than keys; keys filtered downstream while groupIds was not; mixing uid-object keys with a string-array groupIds sized for the old format.","commonSituations":"Batched ingestion slicing keys but not groupIds; merging de-duplicated keys against un-deduplicated group ids; off-by-one zip bug.","solutions":["Omit groupIds if you do not need per-key group assignment - it defaults to all-null.","Keep keys and groupIds zipped at the source and filter them as pairs.","Assert equality before calling update in pipeline code."],"exampleFix":"// before\nawait mgr.update(keys, { groupIds: groups })  // groups.length !== keys.length\n// after\nconst paired = keys.map((k, i) => [k, groups[i] ?? null])\nawait mgr.update(paired.map(p => p[0]), { groupIds: paired.map(p => p[1]) })","handlingStrategy":"validation","validationCode":"function validateKeysAndGroupIds(keys: unknown[], groupIds?: unknown[]): void {\n  if (groupIds && groupIds.length !== keys.length) {\n    throw new Error(`groupIds (${groupIds.length}) must equal keys (${keys.length})`)\n  }\n}","typeGuard":"function areAligned(keys: unknown[], groupIds: unknown[] | undefined): boolean {\n  return !groupIds || groupIds.length === keys.length\n}","tryCatchPattern":"try {\n  await manager.update(keys, { groupIds })\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Number of keys')) {\n    // drop groupIds or realign upstream, then retry\n  }\n  throw e\n}","preventionTips":["Keep keys and groupIds paired; filter as tuples.","Default groupIds to undefined when unused.","Assert length equality in pipeline tests."],"tags":["postgres","record-manager","validation","array-length","upsert"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}