{"record":{"id":"0781d54f75e4eae9","repo":"JuliusBrussee/caveman","slug":"cave-unknown-transform-transformid","errorCode":null,"errorMessage":"cave_unknown_transform:${transformID}","messagePattern":"cave_unknown_transform:(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":2791,"sourceCode":"  const handle = typeof report.recovery_handle === \"string\" && report.recovery_handle.length > 0\n    ? report.recovery_handle\n    : undefined;\n  if (!handle && !bytesEqual(result.stdout, input)) {\n    throw new Error(\"engine_changed_bytes_without_recovery\");\n  }\n  const tokensBefore = validEngineTokenCount(report.tokens_before);\n  const tokensAfter = validEngineTokenCount(report.tokens_after);\n  return {\n    output: result.stdout,\n    ...(handle === undefined ? {} : { handle }),\n    ...(tokensBefore === undefined ? {} : { tokensBefore }),\n    ...(tokensAfter === undefined ? {} : { tokensAfter }),\n  };\n}\n\nfunction engineContentType(transformID: string): string {\n  const match = /^caveman\\.engine\\.([a-z0-9-]+)\\.v1$/.exec(transformID);\n  if (!match) throw new Error(`cave_unknown_transform:${transformID}`);\n  return match[1]!;\n}\n\n\nexport interface SegmentRecoveryProof {\n  transformID: string;\n  /**\n   * `recovered` = the engine returned bytes identical to the original.\n   * `not_smaller` = the engine declined to compress, so there is nothing to\n   * recover and the original bytes are what the model sees.\n   * `mismatch` = recovery did not reproduce the original; the plan fails open\n   * to the original body and nothing may be claimed for this segment.\n   */\n  outcome: \"recovered\" | \"not_smaller\" | \"mismatch\";\n  handle?: string;\n  originalSHA256: string;\n  recoveredSHA256?: string;\n  originalBytes: number;","sourceCodeStart":2773,"sourceCodeEnd":2809,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/runtime.ts#L2773-L2809","documentation":"Thrown by engineContentType when a transform ID does not match the caveman.engine.<name>.v1 pattern, so no engine content type can be derived. This guards the engine-invocation layer, complementing the known-set check in plan application.","triggerScenarios":"Passing a transformID that is not of the form caveman.engine.<lowercase-alnum-dash>.v1 to engineContentType — e.g. an internal call with a raw engine name ('text') or a fully-custom id.","commonSituations":"Custom transform IDs bypassing plan validation; refactors renaming transform ID constants; calling internal engine helpers directly with unvalidated ids.","solutions":["Use canonical transform IDs of the form caveman.engine.<type>.v1","Route all transform selection through plan validation (the known-set check) rather than calling engine helpers directly","Fix any renamed constants so the full dotted form is preserved"],"exampleFix":"// before\nengineContentType(\"text\"); // throws\n\n// after\nengineContentType(\"caveman.engine.text.v1\");","handlingStrategy":"type-guard","validationCode":"const ENGINE_ID = /^caveman\\.engine\\.([a-z0-9-]+)\\.v1$/;\nfunction isEngineTransformId(id: string): boolean {\n  return ENGINE_ID.test(id);\n}","typeGuard":"function isEngineTransform(id: string): id is `caveman.engine.${string}.v1` {\n  return /^caveman\\.engine\\.[a-z0-9-]+\\.v1$/.test(id);\n}","tryCatchPattern":"if (!isEngineTransform(transformID)) throw new TypeError(`not an engine transform: ${transformID}`);\nawait engineContentType(transformID);","preventionTips":["Construct transform ids from typed constants, never string concatenation","Validate ids at the plan boundary so bad values never reach engine helpers","Keep the transform-id pattern in one shared constant"],"tags":["engine","transforms","validation"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}