{"record":{"id":"205ee7363caaed53","repo":"payloadcms/payload","slug":"field-field-label-has-invalid-relationship-r","errorCode":null,"errorMessage":"Field ${field.label} has invalid relationship '${relationship}'.","messagePattern":"Field (.+?) has invalid relationship '(.+?)'\\.","errorType":"exception","errorClass":"InvalidFieldRelationship","httpStatus":500,"severity":"error","filePath":"packages/payload/src/fields/config/sanitize.ts","lineNumber":264,"sourceCode":"      parentIsLocalized,\n      polymorphicJoins,\n    })\n  }\n\n  // Relationship/upload validation\n  if (field.type === 'relationship' || field.type === 'upload') {\n    if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {\n      throw new Error(\n        `Field \"${field.name}\" of type \"${field.type}\" has an empty relationTo array. At least one collection must be specified.`,\n      )\n    }\n\n    if (validRelationships) {\n      const relationships = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]\n\n      relationships.forEach((relationship: string) => {\n        if (!validRelationships.includes(relationship)) {\n          throw new InvalidFieldRelationship(field, relationship)\n        }\n      })\n    }\n  }\n\n  // Upload isSortable default\n  if (field.type === 'upload') {\n    if (!field.admin || !('isSortable' in field.admin)) {\n      field.admin = {\n        isSortable: true,\n        ...field.admin,\n      }\n    }\n  }\n\n  // Slug field: apply defaults, attach generation hook, expose slugify to the server fn.\n  if (field.type === 'slug') {\n    const useAsSlug = field.useAsSlug","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/fields/config/sanitize.ts#L246-L282","documentation":"A relationship/upload field's `relationTo` slug is not in the `validRelationships` allow-list passed during sanitization. `validRelationships` is non-null when Payload restricts which collections a relationship may target (notably for relationships inside arrays/blocks/uploads and during cross-collection validation), so any target outside that list is rejected.","triggerScenarios":"A relationship field nested in an array/block pointing to a collection not allowed in that context; a relationship whose `relationTo` slug has a typo or references a not-yet-defined collection when validRelationships is scoped.","commonSituations":"Renaming a collection without updating references; pointing an array's relationship at a collection that isn't in the allowed set for that container; copy-pasting a relationship across configs with different collection sets.","solutions":["Correct the `relationTo` slug so it matches an existing, allowed collection.","If the collection genuinely should be allowed, review why `validRelationships` is scoped (e.g. upload-file relationships) and adjust the container config.","Ensure the referenced collection is declared earlier or that sanitization order resolves it."],"exampleFix":"// before (Posts collection does not exist or is not allowed here)\n{ type: 'relationship', name: 'post', relationTo: 'Post' }\n// after\n{ type: 'relationship', name: 'post', relationTo: 'posts' }","handlingStrategy":"validation","validationCode":"function assertRelationshipsValid(config) {\n  const allSlugs = new Set(config.collections.map(c => c.slug))\n  const problems = []\n  function walk(fields) {\n    for (const f of fields) {\n      if (f?.type === 'relationship' || f?.type === 'upload') {\n        const rels = Array.isArray(f.relationTo) ? f.relationTo : [f.relationTo]\n        for (const r of rels) if (!allSlugs.has(r)) problems.push(`${f.name} -> ${r}`)\n      }\n      if (Array.isArray(f?.fields)) walk(f.fields)\n      if (Array.isArray(f?.blocks)) for (const b of f.blocks) if (b?.fields) walk(b.fields)\n    }\n  }\n  for (const c of config.collections) walk(c.fields)\n  return problems\n}","typeGuard":"function relationToExists(f: any, knownSlugs: Set<string>): boolean {\n  if (f?.type !== 'relationship' && f?.type !== 'upload') return true\n  const rels = Array.isArray(f.relationTo) ? f.relationTo : [f.relationTo]\n  return rels.every((r: string) => knownSlugs.has(r))\n}","tryCatchPattern":"try {\n  await payload.init({ config })\n} catch (err) {\n  if (err?.name === 'InvalidFieldRelationship' || /invalid relationship/i.test(err?.message ?? '')) {\n    console.error('Bad relationship target:', err?.data)\n  }\n  throw err\n}","preventionTips":["Centralize collection slugs as constants and reference them in `relationTo` to avoid typos.","Re-run the relationship lint after renaming or removing any collection."],"tags":["relationship","upload","config","schema","validation"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}