1:"$Sreact.fragment"
2:I[15579,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Navigation"]
3:I[3013,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],""]
3b:I[41451,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Footer"]
3c:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"OutletBoundary"]
3d:"$Sreact.suspense"
:HL["/blog/posts/pydantic-production-fail-fast/hero.jpg","image"]
:HL["/blog/posts/logo.png","image"]
0:{"buildId":"TlpKRvbES4zzM7LeczAM7","rsc":["$","$1","c",{"children":[[["$","$L2",null,{}],["$","main",null,{"className":"pt-20 md:pt-24","children":["$","article",null,{"children":[["$","header",null,{"className":"border-b border-border","children":["$","div",null,{"className":"container mx-auto px-6 py-14 md:py-20","children":[["$","$L3",null,{"href":"/blog","className":"mb-8 inline-flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-foreground","children":[["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-left mr-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1l729n",{"d":"m12 19-7-7 7-7"}],["$","path","x3x0zl",{"d":"M19 12H5"}],"$undefined"]}],"Blog"]}],["$","div",null,{"className":"grid gap-8 md:grid-cols-[1fr_0.9fr] md:items-start","children":[["$","div",null,{"className":"max-w-3xl","children":[["$","div",null,{"className":"mb-5 flex flex-wrap items-center gap-3 text-sm text-muted-foreground","children":[["$","span",null,{"className":"rounded-md border border-primary/40 bg-primary/10 px-2.5 py-1 text-primary","children":"Backend"}],["$","span",null,{"children":"2026-W20"}],["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":"5 min read"}],null]}],["$","h1",null,{"className":"text-4xl font-bold leading-tight text-balance md:text-6xl","children":"Fail Fast at the Right Boundary — Pydantic Settings in Production"}],["$","p",null,{"className":"mt-6 text-lg leading-relaxed text-muted-foreground md:text-xl","children":"Hardcoded API key defaults work locally and ship secrets to production. A model_validator that refuses to start without the key turns silent misconfig into a loud startup error."}]]}],["$","div",null,{"className":"overflow-hidden rounded-lg border border-border bg-card","children":["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden","children":[null,["$","img",null,{"src":"/blog/posts/pydantic-production-fail-fast/hero.jpg","alt":"A solid brass padlock with its key still inserted, resting on a worn leather-bound logbook with handwritten entries, soft warm desk light, no people, editorial.","className":"h-full w-full object-cover"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-4 top-4 h-[50px] w-[50px] mix-blend-screen"}]]}]}]]}]]}]}],["$","div",null,{"className":"container mx-auto px-6 py-12 md:py-16","children":["$","div",null,{"className":"grid gap-10 lg:grid-cols-[minmax(0,1fr)_280px] lg:items-start","children":[["$","div",null,{"className":"max-w-3xl text-muted-foreground","children":[[["$","h2","h2-0",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The problem"}],"\n",["$","p","p-0",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Configuration defaults that work in development are configuration defaults that break in production. The classic example: a settings class with a hardcoded API key as the default value. It works locally because the key is valid. It works in CI because the test environment inherits the same default. It fails silently in production only after the first email gets queued and not sent — or worse, it sends from the wrong account because the default key is someone's personal credentials that got checked in years ago."}],"\n",["$","p","p-1",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The version of this problem I cleaned up: a ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"BREVO_API_KEY"}]," field with a real transactional email key hardcoded as the Pydantic default value. The key had been in version control long enough that it was baked into the git history. It worked fine. It was also a secret in plaintext in a public-facing codebase."]}],"\n","$L4","\n","$L5","\n","$L6","\n","$L7","\n","$L8","\n","$L9","\n","$La","\n","$Lb","\n","$Lc","\n","$Ld","\n","$Le"],"$Lf",null]}],"$L10"]}]}]]}]}],"$L11"],["$L12","$L13","$L14"],"$L15"]}],"loading":null,"isPartial":false}
4:["$","h2","h2-1",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The approach"}]
5:["$","p","p-2",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Two changes, in order."}]
6:["$","p","p-3",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":[["$","strong","strong-0",{"children":"First"}],": remove the default. ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"BREVO_API_KEY: str = \"\""}]," — empty string, no real credential. The application will start locally without it (dev doesn't send email), and the key gets injected in production via environment variable or secret manager."]}]
7:["$","p","p-4",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":[["$","strong","strong-0",{"children":"Second"}],": add a ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"model_validator"}]," that makes the application fail to start if the key is missing in a production context:"]}]
8:["$","div","pre-0",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["from"]}],["$","span","code-segment-1",{"style":{},"children":[" pydantic "]}],["$","span","code-segment-2",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["import"]}],["$","span","code-segment-3",{"style":{},"children":[" model_validator\n"]}],"\n",["$","span","code-segment-5",{"style":{},"children":["ENVIRONMENT"]}],["$","span","code-segment-6",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}],["$","span","code-segment-7",{"style":{},"children":[" "]}],["$","span","code-segment-8",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["str"]}],["$","span","code-segment-9",{"style":{},"children":[" "]}],["$","span","code-segment-10",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-11",{"style":{},"children":[" "]}],["$","span","code-segment-12",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"development\""]}],["$","span","code-segment-13",{"style":{},"children":["\n"]}],["$","span","code-segment-14",{"style":{},"children":["BREVO_API_KEY"]}],["$","span","code-segment-15",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}],["$","span","code-segment-16",{"style":{},"children":[" "]}],["$","span","code-segment-17",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["str"]}],["$","span","code-segment-18",{"style":{},"children":[" "]}],["$","span","code-segment-19",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-20",{"style":{},"children":[" "]}],["$","span","code-segment-21",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"\""]}],["$","span","code-segment-22",{"style":{},"children":["\n"]}],"\n",["$","span","code-segment-24",{"style":{},"children":[""]}],["$","span","code-segment-25",{"className":"token decorator annotation","style":{"color":"hsl(220, 14%, 71%)"},"children":["@model_validator"]}],["$","span","code-segment-26",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-27",{"style":{},"children":["mode"]}],["$","span","code-segment-28",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-29",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"after\""]}],["$","span","code-segment-30",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-31",{"style":{},"children":["\n"]}],["$","span","code-segment-32",{"style":{},"children":[""]}],["$","span","code-segment-33",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["def"]}],["$","span","code-segment-34",{"style":{},"children":[" "]}],["$","span","code-segment-35",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["_validate_production_secrets"]}],["$","span","code-segment-36",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-37",{"style":{},"children":["self"]}],["$","span","code-segment-38",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-39",{"style":{},"children":[" "]}],["$","span","code-segment-40",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["-"]}],["$","span","code-segment-41",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":[">"]}],["$","span","code-segment-42",{"style":{},"children":[" "]}],["$","span","code-segment-43",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"Settings\""]}],"$L16","$L17","$L18","$L19","$L1a","$L1b","$L1c","$L1d","$L1e","$L1f","$L20","$L21","$L22","$L23","$L24","$L25","$L26","$L27","$L28","$L29","$L2a","$L2b","$L2c","$L2d","$L2e","$L2f","$L30","$L31","$L32","$L33","$L34","$L35","$L36","$L37","$L38","$L39"]]}]}]
9:["$","p","p-5",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The validator runs after all fields are populated. If ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"ENVIRONMENT=production"}]," and the key is empty, the application refuses to start. The error message is explicit about what to set and how to bypass it locally — because someone will inevitably try to start a production-like environment locally and hit this validator, and they need to know the escape hatch immediately."]}]
a:["$","h2","h2-2",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"What I learned"}]
b:["$","p","p-6",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"ENVIRONMENT"}]," field is doing two jobs here: it gates the validator, and it's available to the rest of the application for things like Sentry environment tagging. That's fine — as long as ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"ENVIRONMENT"}]," defaults to ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"\"development\""}]," and the production value has to be set explicitly, the validator only fires when you actually intend to run in production."]}]
c:["$","p","p-7",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The reason for ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"mode=\"after\""}]," (rather than ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"mode=\"before\""}],") is that you want all fields to be resolved from their environment variables before the cross-field validation runs. With ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"mode=\"before\""}]," you'd be validating against raw input, not the final resolved values, and field references would come back as strings from the unprocessed data dict rather than their typed Python values."]}]
d:["$","p","p-8",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["One trap: Pydantic v2's ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"model_validator"}]," replaces the v1 ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"validator"}]," and ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"root_validator"}]," decorators. The ",["$","code","code-3",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"mode=\"after\""}]," variant receives a fully constructed instance (",["$","code","code-4",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"self"}],"), while ",["$","code","code-5",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"mode=\"before\""}]," receives a dict of raw input. Pick based on whether you need the final typed values (after) or want to intercept before any coercion (before)."]}]
e:["$","p","p-9",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"The fail-fast validator doesn't prevent secret sprawl — the key still needs to be rotated if it was ever committed. But it does prevent the class of bug where a stale default silently operates in production, and it makes the operational requirement explicit in the code rather than in a deployment runbook that nobody reads."}]
f:["$","div",null,{"className":"mt-14 border-t border-border pt-8","children":["$","$L3",null,{"href":"/platform","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Start a build",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]]}]}]
10:["$","aside",null,{"className":"hidden lg:block","children":["$","div",null,{"className":"sticky top-24 space-y-4","children":[["$","h3",null,{"className":"text-xs font-semibold uppercase tracking-wider text-primary","children":["More in ","Backend"]}],["$","div",null,{"className":"space-y-4","children":[["$","$L3","idempotency-scheduled-jobs",{"href":"/blog/idempotency-scheduled-jobs","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/idempotency-scheduled-jobs/hero.jpg","alt":"An industrial timestamp clock on a worn wooden desk with two identical printed slips showing the same stamped time stacked beside it, soft window light, no people.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W20"," · ","4 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Idempotency in Scheduled Jobs — The Restart Problem"}]]}]]}],["$","$L3","postgres-notify-ws-delivery",{"href":"/blog/postgres-notify-ws-delivery","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/postgres-notify-ws-delivery/hero.jpg","alt":"Close shot of a server rack with a single blinking amber LED in an otherwise dark row.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W18"," · ","3 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Postgres NOTIFY as a WebSocket Delivery Mechanism"}]]}]]}],["$","$L3","stream-wrapper-pattern",{"href":"/blog/stream-wrapper-pattern","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/stream-wrapper-pattern/hero.jpg","alt":"A clear glass laboratory pipette suspended over a beaker with a single amber drop forming at its tip.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W18"," · ","3 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"The Stream Wrapper Pattern for Transparent Event Capture"}]]}]]}]]}],["$","$L3",null,{"href":"/blog?category=backend","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Read all in ","Backend","$L3a"]}]]}]}]
11:["$","$L3b",null,{}]
12:["$","script","script-0",{"src":"/_next/static/chunks/94245cbda44972fe.js","async":true}]
13:["$","script","script-1",{"src":"/_next/static/chunks/af778fff4a0f4be6.js","async":true}]
14:["$","script","script-2",{"src":"/_next/static/chunks/b096b037d08e2f31.js","async":true}]
15:["$","$L3c",null,{"children":["$","$3d",null,{"name":"Next.MetadataOutlet","children":"$@3e"}]}]
16:["$","span","code-segment-44",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}]
17:["$","span","code-segment-45",{"style":{},"children":["\n"]}]
18:["$","span","code-segment-46",{"style":{},"children":["    "]}]
19:["$","span","code-segment-47",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["if"]}]
1a:["$","span","code-segment-48",{"style":{},"children":[" self"]}]
1b:["$","span","code-segment-49",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}]
1c:["$","span","code-segment-50",{"style":{},"children":["ENVIRONMENT "]}]
1d:["$","span","code-segment-51",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["=="]}]
1e:["$","span","code-segment-52",{"style":{},"children":[" "]}]
1f:["$","span","code-segment-53",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"production\""]}]
20:["$","span","code-segment-54",{"style":{},"children":[" "]}]
21:["$","span","code-segment-55",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["and"]}]
22:["$","span","code-segment-56",{"style":{},"children":[" "]}]
23:["$","span","code-segment-57",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["not"]}]
24:["$","span","code-segment-58",{"style":{},"children":[" self"]}]
25:["$","span","code-segment-59",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}]
26:["$","span","code-segment-60",{"style":{},"children":["BREVO_API_KEY"]}]
27:["$","span","code-segment-61",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}]
28:["$","span","code-segment-62",{"style":{},"children":["\n"]}]
29:["$","span","code-segment-63",{"style":{},"children":["        "]}]
2a:["$","span","code-segment-64",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["raise"]}]
2b:["$","span","code-segment-65",{"style":{},"children":[" ValueError"]}]
2c:["$","span","code-segment-66",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}]
2d:["$","span","code-segment-67",{"style":{},"children":["\n"]}]
2e:["$","span","code-segment-68",{"style":{},"children":["            "]}]
2f:["$","span","code-segment-69",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"BREVO_API_KEY must be set in production. \""]}]
30:["$","span","code-segment-70",{"style":{},"children":["\n"]}]
31:["$","span","code-segment-71",{"style":{},"children":["            "]}]
32:["$","span","code-segment-72",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"Set ENVIRONMENT=development to bypass this check locally.\""]}]
33:["$","span","code-segment-73",{"style":{},"children":["\n"]}]
34:["$","span","code-segment-74",{"style":{},"children":["        "]}]
35:["$","span","code-segment-75",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}]
36:["$","span","code-segment-76",{"style":{},"children":["\n"]}]
37:["$","span","code-segment-77",{"style":{},"children":["    "]}]
38:["$","span","code-segment-78",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["return"]}]
39:["$","span","code-segment-79",{"style":{},"children":[" self"]}]
3a:["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]
3e:null
