{"record":{"id":"bf386bbd8ddfddd5","repo":"garrytan/gstack","slug":"invalid-preamble-tier-tier-in-ctx-tmplpath","errorCode":null,"errorMessage":"Invalid preamble-tier: ${tier} in ${ctx.tmplPath}. Must be 1-4.","messagePattern":"Invalid preamble-tier: (.+?) in (.+?)\\. Must be 1-4\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/resolvers/preamble.ts","lineNumber":82,"sourceCode":"// Standalone export used directly by the resolver registry\nexport { generateTestFailureTriage } from './preamble/generate-test-failure-triage';\n\n// Preamble Composition (tier → sections)\n// ─────────────────────────────────────────────\n// T1: core + upgrade + lake + telemetry + voice(trimmed) + completion\n// T2: T1 + voice(full) + ask + completeness + context-recovery + confusion + checkpoint + context-health\n// T3: T2 + repo-mode + search\n// T4: (same as T3 — TEST_FAILURE_TRIAGE is a separate {{}} placeholder, not preamble)\n//\n// Skills by tier:\n//   T1: browse, setup-cookies, benchmark\n//   T2: investigate, cso, retro, doc-release, setup-deploy, canary, context-save, context-restore, health\n//   T3: autoplan, codex, design-consult, office-hours, ceo/design/eng-review\n//   T4: ship, review, qa, qa-only, design-review, land-deploy\nexport function generatePreamble(ctx: TemplateContext): string {\n  const tier = ctx.preambleTier ?? 4;\n  if (tier < 1 || tier > 4) {\n    throw new Error(`Invalid preamble-tier: ${tier} in ${ctx.tmplPath}. Must be 1-4.`);\n  }\n  const sections = [\n    generatePreambleBash(ctx),\n    ...(ctx.skillName === 'make-pdf' ? [generateMakePdfSetup(ctx)] : []),\n    // Plan-mode-skill semantics stays near the top: after bash (so _SESSION_ID /\n    // _BRANCH / _TEL env vars are live) and before all onboarding gates so\n    // models read the authoritative \"AskUserQuestion satisfies plan mode's\n    // end-of-turn\" rule before any other instruction. Renders for all skills\n    // (not interactive-gated); the text applies universally.\n    generatePlanModeInfo(ctx),\n    generateUpgradeCheck(ctx),\n    generateWritingStyleMigration(ctx),\n    generateLakeIntro(),\n    generateTelemetryPrompt(ctx),\n    generateProactivePrompt(ctx),\n    generateFirstRunGuidance(ctx),\n    generateRoutingInjection(ctx),\n    generateVendoringDeprecation(ctx),","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/scripts/resolvers/preamble.ts#L64-L100","documentation":"generatePreamble() in scripts/resolvers/preamble.ts:82 reads ctx.preambleTier (default 4). The tier selects which preamble sections render (T1 minimal through T4 full). Values outside 1-4 throw, naming ctx.tmplPath so the offending template is identifiable.","triggerScenarios":"Setting `preambleTier: 0` or `preambleTier: 5` in a .tmpl frontmatter. A context-builder bug feeding a non-tier number. Off-by-one when introducing a new tier.","commonSituations":"Misunderstanding the tier scale. Editing tier per the comments but using the wrong integer. Copying tier from a skill that uses a different default.","solutions":["Set preambleTier to 1, 2, 3, or 4 based on the skill's complexity (see the tier table in the comments)","Omit the field to default to 4","If you genuinely need a new tier, extend the bounds and the section assembly in generatePreamble first"],"exampleFix":"// before\npreambleTier: 5\n// after\npreambleTier: 4","handlingStrategy":"type-guard","validationCode":"if (ctx.preambleTier != null && (ctx.preambleTier < 1 || ctx.preambleTier > 4)) {\n  throw new Error(`preambleTier out of range: ${ctx.preambleTier}`);\n}","typeGuard":"const isPreambleTier = (n: number): n is 1 | 2 | 3 | 4 =>\n  Number.isInteger(n) && n >= 1 && n <= 4;","tryCatchPattern":null,"preventionTips":["Use the documented tier-per-skill table in the comments when assigning","Default to tier 4 unless the skill explicitly warrants less","Range-check the value in the context builder, not just in the resolver"],"tags":["template","resolver","preamble","validation"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}