{"record":{"id":"cce0662b38a36616","repo":"hcengineering/platform","slug":"export-failed","errorCode":null,"errorMessage":"Export failed","messagePattern":"Export failed","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"services/export/pod-export/src/server.ts","lineNumber":628,"sourceCode":"            res.status(400).send({ message: 'No documents found to export' })\n          }\n\n          if (exportResult.success) {\n            await sendExportCompletionNotification(\n              measureCtx,\n              targetTxOps,\n              targetWorkspace,\n              targetWsIds,\n              exportResult.exportedDocuments,\n              wsIds,\n              _class\n            )\n          }\n\n          res.status(200).send({ message: 'Export completed' })\n        } catch (err: any) {\n          measureCtx.error('Export failed:', err)\n          res.status(500).send({ message: 'Export failed', error: err.message ?? 'Unknown error' })\n        } finally {\n          await sourceClient.close()\n          await targetClient.close()\n        }\n      } catch (err: any) {\n        measureCtx.error('Export to workspace request failed:', err)\n        const errorMessage = err instanceof ApiError ? err.message : 'Export to workspace request failed'\n        res.status(err instanceof ApiError ? err.code : 500).send({ message: errorMessage })\n      }\n    })\n  )\n\n  app.use((err: any, _req: any, res: any, _next: any) => {\n    measureCtx.warn(err)\n    if (err instanceof ApiError) {\n      res.status(err.code).send({ code: err.code, message: err.message })\n      return\n    }","sourceCodeStart":610,"sourceCodeEnd":646,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/export/pod-export/src/server.ts#L610-L646","documentation":"The export job's outer/inner catch handlers: when the async export pipeline (WorkspaceExporter.export, archiving, target-client writes, notifications) throws, the route logs 'Export failed:' via measureCtx.error and responds 500 with { message: 'Export failed', error: err.message ?? 'Unknown error' }. Note the response of 200 'Export started' is sent before the async job runs, so callers usually observe this failure via logs/notifications rather than the HTTP response.","triggerScenarios":"Any exception during the background export: source/target storage client errors, hierarchy lookups failing on the _class, filesystem tmp-dir failures, zip archiving errors, or sendExportCompletionNotification throwing before res 200 in the inner flow.","commonSituations":"Transient storage outages mid-export, permissions on the temp directory, very large exports hitting memory/disk limits, platform client token issues for the generated sysToken, or notifications webhook failures.","solutions":["Read the measureCtx error log ('Export failed:' with the error) to identify the failing stage.","Retry the export — storage blips are the most common cause; the finally block closes clients so state should be clean.","Verify the target workspace client (targetClient) credentials/connectivity and that the sysToken's workspace is writable.","Check free disk space and tmpdir writability on the export pod for archiving failures."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-flight the source/target storage clients before starting an export\nawait sourceClient.ping()\nawait targetClient.ping()\nawait fs.access(tmpdir(), fs.constants.W_OK)","typeGuard":null,"tryCatchPattern":"try {\n  const res = await exportApi.exportToWorkspace(token, payload)\n  // HTTP 200 only means 'Export started' — poll for completion\n  await pollExportCompletion(res)\n} catch (e) {\n  // job-level failures surface via logs/notifications: check measureCtx 'Export failed:' entries\n  console.error('export job failed', e)\n  await retryExportWithBackoff()\n}","preventionTips":["Remember the route returns 200 before the async job runs — never treat 200 as success","Pre-flight storage connectivity and disk space before large exports","Monitor export pod logs and completion notifications for job outcomes","Retry transient failures; the server closes clients in finally so retries start clean"],"tags":["export","http","server-error","async"],"backgroundTag":"background-job-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}