{"record":{"id":"d3232d9d9eda385f","repo":"thedotmack/claude-mem","slug":"claude-mem-banner-frame-decoding-failed-skipping","errorCode":null,"errorMessage":"claude-mem: banner frame decoding failed, skipping banner:","messagePattern":"claude-mem: banner frame decoding failed, skipping banner:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/npx-cli/banner.ts","lineNumber":38,"sourceCode":"  if (!truecolor) return '\\x1b[38;5;215m';\n  const r = Math.min(255, Math.round(255 * brightness));\n  const g = Math.min(255, Math.round(180 * brightness));\n  const b = Math.min(255, Math.round(122 * brightness));\n  return `\\x1b[38;2;${r};${g};${b}m`;\n}\n\nlet frames: string[] | null = null;\nfunction getFrames(): string[] {\n  if (frames) return frames;\n  // Banner is decorative — if frame payload decoding fails for any reason\n  // (corrupted bundle, mismatched zlib, etc.) we must not break the CLI.\n  // Fail open by returning an empty frame list; playBanner() bails on empty.\n  try {\n    const raw = inflateRawSync(Buffer.from(BANNER.compressed, 'base64')).toString('utf8');\n    frames = raw.split(FRAME_SEP).filter(Boolean);\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n    console.warn('claude-mem: banner frame decoding failed, skipping banner:', err);\n    frames = [];\n  }\n  return frames;\n}\n\n/** One character of a parsed frame plus whether it sits inside an accent span. */\nexport interface FrameCell {\n  ch: string;\n  accent: boolean;\n}\n\n/**\n * Parse a raw span-marked frame (`<x>…</x>` accent markers, `\\n` row\n * separators) into per-character cells carrying an accent flag. Span state\n * carries across newlines, matching the original single-pass styling.\n */\nexport function parseFrameCells(frame: string): FrameCell[][] {\n  const rows: FrameCell[][] = [[]];","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/8bc631a71a487424b866756e43a6efa4574cc66b/src/npx-cli/banner.ts#L20-L56","documentation":"A console.warn from the npx CLI's banner player: inflateRawSync over the base64-embedded BANNER payload threw. The banner is purely decorative, so the code deliberately fails open — frames becomes [] and playBanner() skips the animation instead of breaking the CLI. Seeing this warning means the published bundle's embedded frames are corrupted or the zlib/base64 layer mismatched.","triggerScenarios":"A corrupted or partially-downloaded package in the npm cache (truncated base64 payload); a bundling change that altered BANNER.compressed between encode and decode; manual tampering with the bundle.","commonSituations":"Flaky network producing a truncated package tarball; using a forked/rebundled claude-mem where the banner asset pipeline changed; disk corruption in ~/.npm/_cacche. Functionality is unaffected apart from the animation.","solutions":["Ignore it — cosmetic only, all CLI commands still run","Clear the npm cache and reinstall (npm cache clean --force; npx claude-mem@latest …) to get a clean bundle","If it persists on every machine, report a packaging bug — the embedded BANNER payload is malformed in that release"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["No action needed — the CLI already fails open and skips the banner","Clear npm cache and reinstall if the warning repeats, to rule out a truncated package","Report persistent occurrences upstream so the release's embedded BANNER payload gets fixed"],"tags":["warning","banner","zlib","bundle-corruption","cosmetic"],"backgroundTag":"corrupted-embedded-asset","analyzedSha":"8bc631a71a487424b866756e43a6efa4574cc66b","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}