{"record":{"id":"2ac0b735d4ac81bb","repo":"nocobase/nocobase","slug":"field-options-invalid","errorCode":null,"errorMessage":"field options invalid","messagePattern":"field options invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-data-source-main/src/server/hooks/afterCreateForForeignKeyField.ts","lineNumber":84,"sourceCode":"    }\n\n    if (type === 'uuid') {\n      data['interface'] = 'uuid';\n      data['uiSchema'] = {\n        type: 'string',\n        title: name,\n        'x-component': 'Input',\n        'x-read-pretty': true,\n      };\n    }\n\n    return data;\n  }\n\n  async function createFieldIfNotExists({ values, transaction, interfaceType = null }) {\n    const { collectionName, name } = values;\n    if (!collectionName || !name) {\n      throw new Error(`field options invalid`);\n    }\n    const r = db.getRepository('fields');\n    const instance: FieldModel = await r.findOne({\n      filter: {\n        collectionName,\n        name,\n      },\n      transaction,\n    });\n\n    if (instance) {\n      if (instance.type !== values.type) {\n        throw new Error(`fk type invalid`);\n      }\n      instance.set('sort', 1);\n      instance.set('isForeignKey', true);\n      await instance.save({ transaction });\n      await instance.load({ transaction });","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-data-source-main/src/server/hooks/afterCreateForForeignKeyField.ts#L66-L102","documentation":"createFieldIfNotExists, invoked from the afterCreate hook for foreign key fields, requires both collectionName and name in the field values to locate or create the backing field record. If either is missing the hook cannot proceed and throws this generic validation error.","triggerScenarios":"fields:create (or association field creation) invoked with values lacking collectionName or name — typically a malformed API payload or programmatic field creation.","commonSituations":"Custom scripts calling the fields repository without full values; API clients omitting required keys; broken integrations submitting partial field definitions.","solutions":["Include both collectionName and name in the field values payload","Validate the payload before calling fields:create","Use the standard collection-manager API for creating association fields, which fills these automatically"],"exampleFix":"// before\nawait db.getRepository('fields').create({ values: { type: 'bigint', interface: 'm2o' } });\n// after\nawait db.getRepository('fields').create({ values: { collectionName: 'orders', name: 'customerId', type: 'bigint', interface: 'm2o' } });","handlingStrategy":"validation","validationCode":"function validateFieldValues(values) {\n  if (!values?.collectionName || !values?.name) {\n    throw new Error('field values require collectionName and name');\n  }\n}","typeGuard":"function isCompleteFieldValues(v) {\n  return typeof v === 'object' && v !== null && typeof (v as { collectionName?: unknown }).collectionName === 'string' && typeof (v as { name?: unknown }).name === 'string';\n}","tryCatchPattern":"try {\n  await fieldsRepo.create({ values });\n} catch (e) {\n  if (e.message === 'field options invalid') {\n    console.error('Field payload missing collectionName or name:', values);\n  } else throw e;\n}","preventionTips":["Validate payloads before calling fields:create","Use the collection-manager API which fills defaults automatically","Type your field creation inputs to require collectionName and name"],"tags":["validation","fields","server"],"backgroundTag":"missing-required-argument","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}