{"record":{"id":"4a1a4d4cd8ddabf4","repo":"heygen-com/hyperframes","slug":"rendertolambda-either-sitehandle-or-projectdir-m","errorCode":null,"errorMessage":"[renderToLambda] either siteHandle or projectDir must be supplied","messagePattern":"\\[renderToLambda\\] either siteHandle or projectDir must be supplied","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/aws-lambda/src/sdk/renderToLambda.ts","lineNumber":92,"sourceCode":"  bucketName: string;\n  stateMachineArn: string;\n  outputS3Uri: string;\n  projectS3Uri: string;\n  startedAt: string;\n}\n\n// fallow-ignore-next-line complexity\nexport async function renderToLambda(opts: RenderToLambdaOptions): Promise<RenderHandle> {\n  validateDistributedRenderConfig(opts.config);\n\n  if (!opts.bucketName) {\n    throw new Error(\"[renderToLambda] bucketName is required\");\n  }\n  if (!opts.stateMachineArn) {\n    throw new Error(\"[renderToLambda] stateMachineArn is required\");\n  }\n  if (!opts.siteHandle && !opts.projectDir) {\n    throw new Error(\"[renderToLambda] either siteHandle or projectDir must be supplied\");\n  }\n\n  const executionName = opts.executionName ?? `hf-render-${randomUUID()}`;\n  const ext = formatExtension(opts.config.format);\n  const outputKey = opts.outputKey ?? `renders/${executionName}/output${ext}`;\n  const planOutputS3Prefix = formatS3Uri({\n    bucket: opts.bucketName,\n    key: `renders/${executionName}/`,\n  });\n  const outputS3Uri = formatS3Uri({ bucket: opts.bucketName, key: outputKey });\n\n  const site =\n    opts.siteHandle ??\n    (await deploySite({\n      projectDir: opts.projectDir as string,\n      bucketName: opts.bucketName,\n      region: opts.region,\n      s3: opts.s3,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/aws-lambda/src/sdk/renderToLambda.ts#L74-L110","documentation":"Thrown by renderToLambda when BOTH opts.siteHandle and opts.projectDir are absent. The function needs a project to render: either a previously-deployed SiteHandle (skips the tar+PUT) or a local projectDir (deploySite runs inline). Supplying neither means there is nothing to render, and the guard prevents a downstream undefined dereference in deploySite. Passing one of the two resolves it.","triggerScenarios":"Caller assumes projectDir is required and siteHandle optional but passes neither; siteHandle is conditionally set and the condition evaluated false; an options builder that omits both when a feature flag is off.","commonSituations":"Branching logic that sets siteHandle only on cache-hit and projectDir only on cache-miss but leaves a path where neither is set; spreading a partial config object; TS optional fields left undefined at runtime despite the type.","solutions":["Always provide projectDir as a baseline; layer siteHandle on top when you have a cached handle.","Restructure the caller so exactly one branch runs: if (siteHandle) use it, else use projectDir.","Add a TS-level assertion or branded type so the 'both undefined' state is unrepresentable.","Default projectDir to a known directory when no siteHandle exists."],"exampleFix":"// before\nconst handle = cache.get(id); // undefined on miss\nawait renderToLambda({ config, bucketName, stateMachineArn, siteHandle: handle });\n\n// after\nconst opts = handle\n  ? { siteHandle: handle }\n  : { projectDir: './dist' };\nawait renderToLambda({ config, bucketName, stateMachineArn, ...opts });","handlingStrategy":"validation","validationCode":"function assertRenderSource(opts: {\n  siteHandle?: unknown; projectDir?: string;\n}): void {\n  if (!opts.siteHandle && !opts.projectDir) {\n    throw new Error('either siteHandle or projectDir must be supplied');\n  }\n}","typeGuard":"const hasRenderSource = (o: { siteHandle?: unknown; projectDir?: string }): boolean =>\n  Boolean(o.siteHandle) || Boolean(o.projectDir);","tryCatchPattern":null,"preventionTips":["Structure the caller so exactly one of siteHandle/projectDir is set on every branch.","Default to projectDir when no cached handle exists.","Make the 'both undefined' state unrepresentable with a discriminated union."],"tags":["validation","render","config","aws-lambda"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}