Skip to content

Commit cd1bf95

Browse files
jrusso1020claude
andcommitted
fix(producer): font cache writes to /tmp on Lambda (read-only \$HOME)
The deterministic Google Fonts cache was rooted at `\$HOME/.cache/hyperframes/fonts`, which fails on AWS Lambda — the runtime's `\$HOME` resolves to a `/home/sbx_*` directory tree that's read-only. `mkdirSync(..., { recursive: true })` can't create that path and the plan stage trips with `ENOENT: no such file or directory, mkdir '/home/sbx_user1051/.cache/hyperframes/fonts/space-mono'` on every Lambda render that pulls a Google Font (i.e. every distributed fixture using `@import url("https://fonts.googleapis.com/...")`). Detect Lambda via `\$AWS_LAMBDA_FUNCTION_NAME` and route the cache to `tmpdir()/hyperframes/fonts` in that case. Lambda's `/tmp` survives across invocations on a warm container, so cache hit rate is the same as non-Lambda runs. Also honor an explicit `\$HYPERFRAMES_FONT_CACHE_DIR` override for adopters who want a different location regardless of the runtime. Surfaced while verifying webm distributed end-to-end on real AWS — the same bug affects mp4 fixtures using Google Fonts; webm just happened to be the one I tried first. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b3f5842 commit cd1bf95

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

packages/producer/src/services/deterministicFonts.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2-
import { homedir } from "node:os";
2+
import { homedir, tmpdir } from "node:os";
33
import { join } from "node:path";
44

55
import { parseHTML } from "linkedom";
@@ -330,7 +330,23 @@ function warnUnresolvedFonts(unresolved: string[]): void {
330330
// Google Fonts on-demand fetch + local cache
331331
// ---------------------------------------------------------------------------
332332

333-
const GOOGLE_FONTS_CACHE_DIR = join(homedir(), ".cache", "hyperframes", "fonts");
333+
// On AWS Lambda (and other read-only-FS execution environments), $HOME
334+
// resolves to a directory tree the worker can't write to (`/home/sbx_*`
335+
// is read-only; only `/tmp` is writable). Fall back to the OS temp dir
336+
// when we detect we're running inside a Lambda invocation, and honor an
337+
// explicit `HYPERFRAMES_FONT_CACHE_DIR` for callers who want a different
338+
// location regardless. The cache lives between invocations on warm
339+
// containers — Lambda's `/tmp` survives across invocations of the same
340+
// container — so cache hit rate is unchanged from non-Lambda runs.
341+
function resolveFontCacheRoot(): string {
342+
const explicit = process.env.HYPERFRAMES_FONT_CACHE_DIR;
343+
if (explicit && explicit.length > 0) return explicit;
344+
if (process.env.AWS_LAMBDA_FUNCTION_NAME) {
345+
return join(tmpdir(), "hyperframes", "fonts");
346+
}
347+
return join(homedir(), ".cache", "hyperframes", "fonts");
348+
}
349+
const GOOGLE_FONTS_CACHE_DIR = resolveFontCacheRoot();
334350

335351
// Chrome UA triggers woff2 responses from Google Fonts CSS API
336352
const WOFF2_USER_AGENT =

0 commit comments

Comments
 (0)