hcengineering/platform · error

Cannot resolve a ProjectDocument for document ${document._id

Error message

Cannot resolve a ProjectDocument for document ${document._id}

What it means

getControlledDocumentLinkFragment looks up the ProjectDocument that references a given ControlledDocument via findOne on { document: document._id } and throws when no such ProjectDocument exists. The library requires every controlled document link to resolve to a project document to build a valid location.

Source

Thrown at plugins/controlled-documents-resources/src/utils.ts:208

      },
      sort: {
        '$lookup.project.createdOn': SortingOrder.Descending
      },
      limit: 1
    }
  )

  const project = projectDoc?.project ?? documents.ids.NoProject

  return getProjectDocumentLink(targetDocument, project)
}

export async function getControlledDocumentLinkFragment (document: ControlledDocument): Promise<Location> {
  const client = getClient()
  const targetDocument = await client.findOne(documents.class.ProjectDocument, { document: document._id })

  if (targetDocument === undefined) {
    throw new Error('Cannot resolve a ProjectDocument for document ' + document._id)
  }

  const project = targetDocument.project ?? documents.ids.NoProject
  return getProjectDocumentLink(document, project)
}

export interface TeamPopupData {
  controlledDoc: ControlledDocument
  requestClass: Ref<Class<DocumentRequest>>
  requireSignature?: boolean
}

export async function sendReviewRequest (
  client: TxOperations,
  controlledDoc: ControlledDocument,
  reviewers: Array<Ref<Employee>>
): Promise<void> {
  const approveTx = client.txFactory.createTxUpdateDoc(controlledDoc._class, controlledDoc.space, controlledDoc._id, {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Create the missing ProjectDocument linked to the controlled document via { document: document._id }
  2. Restore the deleted ProjectDocument or remove the orphaned ControlledDocument
  3. Guard callers to check existence with client.findOne before requesting a link fragment
  4. Fix creation flow so a ProjectDocument is always created alongside the controlled document

Example fix

// before
const loc = await getControlledDocumentLinkFragment(doc) // throws
// after
const pd = await client.findOne(documents.class.ProjectDocument, { document: doc._id })
if (pd === undefined) return undefined
const loc = await getControlledDocumentLinkFragment(doc)
Defensive patterns

Strategy: validation

Validate before calling

const pd = await client.findOne(documents.class.ProjectDocument, { document: controlledDoc._id })
if (pd === undefined) return undefined // or create the missing ProjectDocument

Type guard

async function hasProjectDocument(client: Client, doc: ControlledDocument): Promise<boolean> {
  return (await client.findOne(documents.class.ProjectDocument, { document: doc._id })) !== undefined
}

Try / catch

try {
  return await getControlledDocumentLinkFragment(doc)
} catch (err) {
  if (err.message.startsWith('Cannot resolve a ProjectDocument')) {
    return undefined
  }
  throw err
}

Prevention

When it happens

Trigger: Requesting a link fragment for a ControlledDocument whose backing ProjectDocument was never created or was deleted; passing a _id from another hierarchy or a stale reference.

Common situations: Data migration creating controlled documents without project documents; hard-deleting project documents while controlled documents remain; UI/bookmarks referencing removed documents.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/9e28b082993f3511. Report an issue: GitHub.