{"id":"145fa6d3d473de0a","repo":"prisma/prisma","slug":"psl-preset-not-list","errorCode":"PSL_PRESET_NOT_LIST","errorMessage":"Field \"${model.name}.${field.name}\" uses a field-preset call as a list element type. Presets cannot be list elements; remove \"[]\" or use a scalar type.","messagePattern":"Field \"(.+?)\\.(.+?)\" uses a field-preset call as a list element type\\. Presets cannot be list elements; remove \"\\[\\]\" or use a scalar type\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/2-sql/2-authoring/contract-psl/src/psl-field-resolution.ts","lineNumber":430,"sourceCode":"        continue;\n      }\n      const resolved = resolveFieldTypeDescriptor(resolveInput);\n      if (!resolved.ok) {\n        if (!resolved.alreadyReported) {\n          diagnostics.push({\n            code: 'PSL_UNSUPPORTED_FIELD_TYPE',\n            message: `Field \"${model.name}.${field.name}\" type \"${field.typeName}\" is not supported in SQL PSL provider v1`,\n            sourceId,\n            span: field.span,\n          });\n        }\n        continue;\n      }\n      // Field presets are complete declarations — they carry their own codec\n      // and do not compose with `[]` list-of semantics. Reject early.\n      if (resolved.presetContributions) {\n        diagnostics.push({\n          code: 'PSL_PRESET_NOT_LIST',\n          message: `Field \"${model.name}.${field.name}\" uses a field-preset call as a list element type. Presets cannot be list elements; remove \"[]\" or use a scalar type.`,\n          sourceId,\n          span: field.span,\n        });\n        continue;\n      }\n      scalarCodecId = resolved.descriptor.codecId;\n      descriptor = resolved.descriptor;\n    } else {\n      const resolved = resolveFieldTypeDescriptor(resolveInput);\n      if (!resolved.ok) {\n        if (!resolved.alreadyReported) {\n          diagnostics.push({\n            code: 'PSL_UNSUPPORTED_FIELD_TYPE',\n            message: `Field \"${model.name}.${field.name}\" type \"${field.typeName}\" is not supported in SQL PSL provider v1`,\n            sourceId,\n            span: field.span,\n          });","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/prisma/prisma/blob/1243cdffbec0506c595ac8fd5865fe258c336fa0/packages/2-sql/2-authoring/contract-psl/src/psl-field-resolution.ts#L412-L448","documentation":"A field is declared as a list (`[]`) whose element type is a field-preset call (e.g. `temporal.updatedAt()[]`). Field presets are complete field declarations — they carry their own codec, default, nullability, and id/unique semantics — so they cannot be composed with list-of semantics. Prisma Next rejects this at resolution time so the contract never carries an ambiguous preset-as-list-element column.","triggerScenarios":"Raised in the `isListField` branch after `resolveFieldTypeDescriptor` succeeds (`resolved.ok === true`) but `resolved.presetContributions` is defined, indicating the element type resolved through the field-preset dispatch path (a descriptor was found in `authoringContributions.field`).","commonSituations":"Trying to apply `temporal.updatedAt()` or `id.uuidv7String()` to every element of a list field; mechanically suffixing a migrated preset field with `[]` during a Prisma-6-to-Prisma-Next port; misunderstanding presets as element-level type constructors.","solutions":["Remove the `[]` from the field — presets are single-column declarations, not list element types.","If you truly need a list of timestamps or ids, declare a plain scalar list (e.g. `DateTime[]`) and manage defaults per-row in application code or via a child relation.","Use a type constructor (not a preset) if a list of a target-native type is required."],"exampleFix":"// before\nmodel Event {\n  id      String @id\n  stamps  temporal.updatedAt()[]\n}\n\n// after — scalar list, no preset\nmodel Event {\n  id      String     @id\n  stamps  DateTime[]\n}","handlingStrategy":"validation","validationCode":"// A field preset is a registered preset-call type name (e.g. @prisma-next/...). Detect any preset call used with [] suffix.\nconst PRESET_CALL = /([A-Za-z_][\\w.]*)\\s*\\(.*?\\)\\s*\\[\\]/;\nfunction findPresetAsListElement(psl: string): { model: string; field: string }[] {\n  const out: { model: string; field: string }[] = [];\n  for (const m of psl.matchAll(/model\\s+(\\w+)\\s*\\{([\\s\\S]*?)\\}/g)) {\n    for (const f of m[2].matchAll(/^\\s*(\\w+)\\s+([\\s\\S]+?)/m)) {\n      if (PRESET_CALL.test(f[2])) out.push({ model: m[1], field: f[1] });\n    }\n  }\n  return out;\n}","typeGuard":"null","tryCatchPattern":"const result = await provider.load(context);\nif (!result.ok) {\n  const presetList = result.error.diagnostics.filter((d) => d.code === 'PSL_PRESET_NOT_LIST');\n  for (const d of presetList) { /* drop the [] from the offending field's type */ }","preventionTips":["Field presets are complete, self-contained declarations - never append [] to make them lists.","If you need multiple preset values, declare one field per element or use a supported scalar list instead.","Treat a preset call like a sealed type: it brings its own codec and cannot be composed with list-of semantics."],"tags":["psl","schema","field-preset","scalar-list"],"analyzedSha":"1243cdffbec0506c595ac8fd5865fe258c336fa0","analyzedAt":"2026-08-01T19:42:02.087Z","schemaVersion":2}