{"record":{"id":"8bdb29438a2a4d67","repo":"heygen-com/hyperframes","slug":"unknown-effect-type-type","errorCode":null,"errorMessage":"Unknown effect type: ${type}","messagePattern":"Unknown effect type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/audio/audioFxGraph.ts","lineNumber":353,"sourceCode":"  waveshaper,\n  \"delay-feedback\": delayFeedback,\n  \"chorus-lfo\": chorusLfo,\n  \"allpass-phaser\": allpassPhaser,\n  convolver,\n};\n\n/** Effect ids whose Web Audio node needs a worklet module registered first. */\nexport function chainNeedsWorklets(chain: HfAudioFxChain): boolean {\n  return chain.nodes.some((node) => getAudioFxDef(node.type)?.web.startsWith(\"worklet-\") ?? false);\n}\n\nexport function buildFxNode(\n  ctx: BaseAudioContext,\n  type: string,\n  params: HfAudioFxParamValues,\n): FxNodeHandle {\n  const def = getAudioFxDef(type);\n  if (!def) throw new Error(`Unknown effect type: ${type}`);\n  const resolved = normalizeAudioFxParams(type, params);\n  // One-pole is a different node type, not a different parameter value.\n  if ((type === \"highpass\" || type === \"lowpass\") && String(resolved.poles) === \"1\") {\n    return onePoleBuilder(type)(ctx, resolved);\n  }\n  const builder = BUILDERS[def.web];\n  if (!builder) throw new Error(`No Web Audio builder for ${def.web}`);\n  return builder(ctx, resolved);\n}\n\nexport interface FxChainHandle {\n  input: AudioNode;\n  output: AudioNode;\n  /** Re-parameterise in place when the shape is unchanged; false if a rebuild is needed. */\n  update(chain: HfAudioFxChain): boolean;\n  dispose(): void;\n}\n","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/audio/audioFxGraph.ts#L335-L371","documentation":"buildFxNode() looks up the effect `type` in the registry (getAudioFxDef/BY_ID, keyed by HF_AUDIO_FX ids) and throws if no definition exists. This guards the runtime Web Audio graph builder — only effect ids declared in HF_AUDIO_FX can be instantiated. Unlike parseAudioFxChain (which rejects unknown ids at load time), this fires at graph construction, e.g. when code assembles a node programmatically with a typo'd or outdated id.","triggerScenarios":"Calling buildFxNode(ctx, 'compressor', {...}) when the real id is 'worklet-compressor'; passing a user-typed or LLM-generated effect name not in HF_AUDIO_FX_IDS; a stale plugin/block referencing an id that was renamed or removed in a HyperFrames version bump.","commonSituations":"Custom composition authoring by hand with a guessed effect id; upgrading HyperFrames after an effect was renamed; loading a chain that bypassed parseAudioFxChain validation (e.g. constructed in memory).","solutions":["Use only ids exported in HF_AUDIO_FX_IDS; import and check membership before building.","If you have a chain object, run it through parseAudioFxChain (or at least check each node.type against HF_AUDIO_FX_IDS) before calling buildFxNode so the error surfaces early with a clear message.","Update to the current effect id after a rename — check the HF_AUDIO_FX array in packages/core/src/audioFx.ts for the canonical list."],"exampleFix":"// before\nconst node = buildFxNode(ctx, \"compressor\", {}); // throws Unknown effect type\n\n// after — guard against the registry first\nimport { HF_AUDIO_FX_IDS } from \"@hyperframes/core\";\nconst type = HF_AUDIO_FX_IDS.includes(\"worklet-compressor\") ? \"worklet-compressor\" : undefined;\nif (!type) throw new Error(`effect not available`);\nconst node = buildFxNode(ctx, type, {});","handlingStrategy":"type-guard","validationCode":"import { HF_AUDIO_FX_IDS } from \"@hyperframes/core\";\nconst known = new Set(HF_AUDIO_FX_IDS);\nif (!known.has(type)) throw new Error(`unsupported effect id: ${type}`);\nconst node = buildFxNode(ctx, type, params);","typeGuard":"import { HF_AUDIO_FX_IDS } from \"@hyperframes/core\";\nconst FX_ID_SET = new Set(HF_AUDIO_FX_IDS);\nfunction isAudioFxId(type: string): type is string {\n  return FX_ID_SET.has(type);\n}","tryCatchPattern":"try { buildFxNode(ctx, type, params); }\ncatch (err) { if (/Unknown effect type/.test(String(err))) { /* pick a supported id */ } else throw err; }","preventionTips":["Source effect ids only from HF_AUDIO_FX_IDS, never hard-code or guess.","Validate programmatic chains with parseAudioFxChain before building the graph.","After a HyperFrames upgrade, re-check the canonical HF_AUDIO_FX list for renames."],"tags":["audio","effects","validation","registry","runtime"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}