{"record":{"id":"13f53e59237eb271","repo":"Budibase/budibase","slug":"can-t-bulk-import-relationship-fields-for-internal","errorCode":null,"errorMessage":"Can't bulk import relationship fields for internal databases, found value in field \"${fieldName}\"","messagePattern":"Can't bulk import relationship fields for internal databases, found value in field \"(.+?)\"","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/table/utils.ts","lineNumber":151,"sourceCode":"  const keepCouchId = !!opts?.keepCouchId\n  for (let i = 0; i < data.length; i++) {\n    let row = data[i]\n    row._id = (keepCouchId && row._id) || generateRowID(table._id!)\n    row.type = \"row\"\n    row.tableId = table._id\n\n    // We use a reference to table here and update it after input processing,\n    // so that we can auto increment auto IDs in imported data properly\n    row = await inputProcessing(userId, table, row, {\n      noAutoRelationships: true,\n    })\n\n    // However here we must reference the original table, as we want to mutate\n    // the real schema of the table passed in, not the clone used for\n    // incrementing auto IDs\n    for (const [fieldName, schema] of Object.entries(originalTable.schema)) {\n      if (schema.type === FieldType.LINK && data.find(row => row[fieldName])) {\n        throw new HTTPError(\n          `Can't bulk import relationship fields for internal databases, found value in field \"${fieldName}\"`,\n          400\n        )\n      }\n\n      if (\n        (schema.type === FieldType.OPTIONS ||\n          schema.type === FieldType.ARRAY) &&\n        row[fieldName]\n      ) {\n        const isArray = Array.isArray(row[fieldName])\n\n        // Add option to inclusion constraints\n        const rowVal = isArray ? row[fieldName] : [row[fieldName]]\n        let merged = [...schema.constraints!.inclusion!, ...rowVal]\n        let superSet = new Set(merged)\n        schema.constraints!.inclusion = Array.from(superSet)\n        schema.constraints!.inclusion.sort()","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/table/utils.ts#L133-L169","documentation":"Bulk row import (CSV/JSON into a table) cannot populate relationship (link) fields when the table lives in the internal CouchDB database; links must be created through the link APIs after rows exist. importToRows throws HTTP 400 if any imported row has a non-empty value in a FieldType.LINK column.","triggerScenarios":"Uploading a CSV/JSON bulk import where any row contains a truthy value under a column whose schema type is \"link\" in the original table's schema.","commonSituations":"Exporting rows from another app including link columns and re-importing them as-is; templates/migrations that assumed relationships import like scalar fields (true for SQL datasources, not internal).","solutions":["Remove the link columns from the CSV/JSON before import, then create relationships via the link API or relationship UI afterwards","Import into a SQL (external) datasource if relationship data must be bulk-loaded","Split the workflow: import scalar fields first, then run a script mapping natural keys to row IDs to build links"],"exampleFix":"// before\ncsv = \"name,tags\\nrow1,tag1\"\nawait api.import(tableId, csv) // tags is a link field\n// after\ncsv = \"name\\nrow1\"\nawait api.import(tableId, csv)\nawait api.createLink(tableId, rowId, 'tags', tagRowIds)","handlingStrategy":"validation","validationCode":"function assertNoLinkData(table, rows) {\n  for (const [name, schema] of Object.entries(table.schema || {})) {\n    if (schema.type === \"link\" && rows.some(r => r[name])) {\n      throw new Error(`remove link column ${name} before bulk import`)\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.importRows(tableId, rows)\n} catch (e) {\n  if (e?.status === 400 && /relationship fields/.test(e.message)) {\n    const field = e.message.match(/field \\\"(.+?)\\\"/)?.[1]\n    // strip that column from rows, import, then build links via API\n  } else throw e\n}","preventionTips":["Strip link columns from CSV/JSON exports before re-import","Build relationships post-import via the link API","Bulk-load link data only against external (SQL) datasources","Document import format limits for internal tables"],"tags":["import","relationships","internal-table"],"backgroundTag":"bulk-import-unsupported-field","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}