{"record":{"id":"f98b1205006979a3","repo":"twentyhq/twenty","slug":"failed-to-request-artifact-import-for-call-recordi","errorCode":null,"errorMessage":"failed to request artifact import for call recording ${callRecordingId}","messagePattern":"failed to request artifact import for call recording (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-apps/public/call-recorder/src/logic-functions/flows/handle-recall-webhook.util.ts","lineNumber":200,"sourceCode":"  return {\n    status: 'queued',\n    event: webhookEvent.event,\n    callRecordingId: callRecording.id,\n  };\n};\n\nconst requestCallRecordingArtifactsImportOrThrow = async ({\n  callRecordingId,\n}: {\n  callRecordingId: string;\n}): Promise<void> => {\n  const importRequested = await requestCallRecordingArtifactsImport({\n    callRecordingId,\n    requestedAt: new Date().toISOString(),\n  });\n\n  if (!importRequested) {\n    throw new Error(\n      `failed to request artifact import for call recording ${callRecordingId}`,\n    );\n  }\n};\n\nconst findMatchingCallRecording = async ({\n  client,\n  webhookEvent,\n}: {\n  client: CoreApiClient;\n  webhookEvent: RecallWebhookEvent;\n}): Promise<CallRecordingRecord | undefined> => {\n  if (!isUndefined(webhookEvent.callRecordingIdFromMetadata)) {\n    return (\n      await findCallRecordingsByFilter(client, {\n        id: { eq: webhookEvent.callRecordingIdFromMetadata },\n      })\n    )[0];","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-apps/public/call-recorder/src/logic-functions/flows/handle-recall-webhook.util.ts#L182-L218","documentation":"Inside the Recall webhook handler, after a matching `CallRecording` is found, `requestCallRecordingArtifactsImportOrThrow` dispatches a logic-function call (`requestCallRecordingArtifactsImport`) to queue media/artifact import for that recording. That dispatcher returns a truthy/falsy result; if it returns falsy the handler throws, which surfaces as a non-2xx to Svix so the webhook is retried. The error therefore signals a dispatch/queue failure, not a media download failure.","triggerScenarios":"The dispatch target logic function is misconfigured/unpublished, the CallRecording id passed to the dispatcher does not resolve, the dispatcher hits a transient platform error and returns `false`, or the call recording is in a state that refuses a new import request (e.g. already importing/terminal).","commonSituations":"A new deployment where the artifact-import logic function was not published or its universal identifier changed; a Recall webhook arriving for a recording that was concurrently marked failed/deleted; a platform-level throttle that makes the dispatch return falsy.","solutions":["Confirm the target logic function invoked by `requestCallRecordingArtifactsImport` is published and its universal identifier matches the dispatch.","Inspect logs around the dispatch call for the underlying reason it returned falsy (the dispatcher should log before returning false).","Verify the `callRecordingId` is in a state that accepts an import request (not already terminal/importing).","Because a throw triggers Svix retry, a transient platform error often resolves on the next retry — check whether the recording eventually imports before chasing a code fix."],"exampleFix":"// before\nconst importRequested = await requestCallRecordingArtifactsImport({\n  callRecordingId,\n  requestedAt: new Date().toISOString(),\n});\nif (!importRequested) {\n  throw new Error(`failed to request artifact import for call recording ${callRecordingId}`);\n}\n\n// after — capture and propagate the dispatcher's failure reason\nconst importResult = await requestCallRecordingArtifactsImport({\n  callRecordingId,\n  requestedAt: new Date().toISOString(),\n});\nif (!importResult?.ok) {\n  throw new Error(\n    `failed to request artifact import for call recording ${callRecordingId}: ${importResult?.error ?? 'dispatcher returned falsy'}`,\n  );\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm the target logic function is published before dispatching.\nconst published = await isLogicFunctionPublished(ARTIFACT_IMPORT_LF_IDENTIFIER);\nif (!published) {\n  throw new Error(`Artifact-import logic function ${ARTIFACT_IMPORT_LF_IDENTIFIER} is not published`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await requestCallRecordingArtifactsImportOrThrow({ callRecordingId });\n} catch (error) {\n  // A throw becomes a non-2xx → Svix retries. Log the failure id for correlation\n  // but allow the throw to propagate so the webhook is retried.\n  console.error(`[call-recorder] artifact-import dispatch failed for ${callRecordingId}: ${error instanceof Error ? error.message : String(error)}`);\n  throw error;\n}","preventionTips":["Publish the artifact-import logic function in every environment before enabling the webhook route.","Make the dispatcher return a structured result (ok/error) instead of a bare boolean so failures are diagnosable.","Treat a thrown error here as a retry signal (Svix) rather than a permanent failure.","Log the callRecordingId and dispatch target identifier on every attempt for correlation."],"tags":["webhook","recall","call-recorder","dispatch","retry"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}