{"record":{"id":"2d7ab8f69d63f113","repo":"hcengineering/platform","slug":"getdisplaymedia-not-supported","errorCode":null,"errorMessage":"getDisplayMedia not supported","messagePattern":"getDisplayMedia not supported","errorType":"exception","errorClass":"DeviceUnsupportedError","httpStatus":null,"severity":"error","filePath":"desktop/src/ui/screenShare.ts","lineNumber":30,"sourceCode":"// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nimport log from 'electron-log'\nimport love from '@hcengineering/love'\nimport { setCustomCreateScreenTracks } from '@hcengineering/love-resources'\nimport { showPopup } from '@hcengineering/ui'\nimport { Track, LocalTrack, LocalAudioTrack, LocalVideoTrack, ParticipantEvent, TrackInvalidError, ScreenShareCaptureOptions, DeviceUnsupportedError, ScreenSharePresets } from 'livekit-client'\nimport { ipcMainExposed } from './typesUtils'\n\nexport function defineGetDisplayMedia (): void {\n  if (navigator?.mediaDevices === undefined) {\n    console.warn('mediaDevices API not available')\n    return\n  }\n\n  if (navigator.mediaDevices.getDisplayMedia === undefined) {\n    throw new DeviceUnsupportedError('getDisplayMedia not supported')\n  }\n\n  navigator.mediaDevices.getDisplayMedia = async (opts?: DisplayMediaStreamOptions): Promise<MediaStream> => {\n    if (opts === undefined) {\n      throw new Error('opts must be provided')\n    }\n\n    const ipcMain = ipcMainExposed()\n    const sources = await ipcMain.getScreenSources()\n\n    const hasAccess = await ipcMain.getScreenAccess()\n    if (!hasAccess) {\n      log.error('No screen access granted')\n      throw new Error('No screen access granted')\n    }\n\n    return await new Promise<MediaStream>((resolve, reject) => {\n      let wasSelected = false","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/desktop/src/ui/screenShare.ts#L12-L48","documentation":"The mail service endpoint in services/mail/pod-mail/src/main.ts responds with HTTP 400 and { err: \"'to' is missing\" } when the send-mail request body lacks the 'to' recipient address. handleSendMail checks required fields in order (text/html, subject, to, from) and stops at the first missing one, so receiving this error means text/html and subject were present but 'to' was not.","triggerScenarios":"POSTing to the mail endpoint with subject and a body (text or html) but no 'to' property in the JSON body, or 'to' serialized as null/undefined.","commonSituations":"Recipients list built from an optional upstream field (e.g. a user without an email); template-driven sends where the recipient placeholder was never filled; batch scripts iterating records with missing contact info.","solutions":["Add a valid 'to' recipient address (string or array of addresses) to the request body.","Filter upstream recipient lists to entries that actually have an email before calling the endpoint.","Skip or queue records without recipients instead of calling the endpoint with an empty/undefined 'to'.","Log the payload at the caller to confirm 'to' survives serialization."],"exampleFix":"// before\nconst body = { from, subject, text, to: user.email } // user.email may be undefined\n// after\nif (!user.email) throw new Error(`User ${user.id} has no email`)\nconst body = { from, subject, text, to: user.email }","handlingStrategy":"validation","validationCode":"if (!to || (Array.isArray(to) && to.length === 0)) {\n  throw new Error('at least one recipient (to) is required before calling the mail endpoint')\n}","typeGuard":"function hasRecipient(body: unknown): body is { to: string | string[]; [k: string]: unknown } {\n  const t = (body as any)?.to\n  return typeof t === 'string' ? t.length > 0 : Array.isArray(t) && t.length > 0\n}","tryCatchPattern":"const res = await fetch(mailUrl, { method: 'POST', body })\nif (res.status === 400) {\n  const { err } = await res.json()\n  if (err === \"'to' is missing\") {\n    // skip/queue this record and log which entity had no recipient\n  }\n}","preventionTips":["Filter recipient lists upstream so records without an email never reach the send call.","Fail fast with a clear message when an entity lacks a recipient instead of sending an incomplete payload.","Include the source entity id in logs when skipping unsendable mail."],"tags":["http-400","validation","missing-field","mail"],"backgroundTag":"missing-request-field","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}