{"record":{"id":"90874fa0e0316518","repo":"can1357/oh-my-pi","slug":"cachedcontent-cannot-be-combined-with-request-leve","errorCode":null,"errorMessage":"cachedContent cannot be combined with request-level ${incompatibleFields.join(\", \")}","messagePattern":"cachedContent cannot be combined with request-level (.+?)","errorType":"validation","errorClass":"AIError.ValidationError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/providers/google-shared.ts","lineNumber":891,"sourceCode":"\t\tif (options.signal.aborted) {\n\t\t\tthrow new AIError.AbortError(\"Request aborted\");\n\t\t}\n\t\tconfig.abortSignal = options.signal;\n\t}\n\n\tif (options.cachedContent !== undefined) {\n\t\t// Blank names are never valid resource references; anything else stays\n\t\t// opaque so we do not invent format/model/project checks here.\n\t\tif (options.cachedContent.trim().length === 0) {\n\t\t\tthrow new AIError.ValidationError(\"cachedContent must not be blank\");\n\t\t}\n\t\tconst incompatibleFields = [\n\t\t\tconfig.systemInstruction !== undefined && \"systemInstruction\",\n\t\t\tconfig.tools !== undefined && \"tools\",\n\t\t\tconfig.toolConfig !== undefined && \"toolConfig\",\n\t\t].filter((field): field is string => Boolean(field));\n\t\tif (incompatibleFields.length > 0) {\n\t\t\tthrow new AIError.ValidationError(\n\t\t\t\t`cachedContent cannot be combined with request-level ${incompatibleFields.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\tconfig.cachedContent = options.cachedContent;\n\t}\n\n\treturn {\n\t\tmodel: model.id,\n\t\tcontents,\n\t\tconfig,\n\t};\n}\n\n/**\n * Drive the `streamGoogle` / `streamGoogleVertex` event flow: build the assistant message,\n * push start/done/error events, run `consumeGoogleStream`, and translate thrown errors into\n * the canonical `error` event shape.\n *","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/providers/google-shared.ts#L873-L909","documentation":"Google's context caching API does not allow request-level systemInstruction, tools, or toolConfig alongside cachedContent (the cache already carries them). buildGoogleGenerateContentParams detects any of these set together with cachedContent and throws AIError.ValidationError listing the offending fields.","triggerScenarios":"Passing cachedContent plus systemInstruction, tools, or toolConfig in the same request options — e.g. standard agent params (with tools attached) reused for a cache-backed call.","commonSituations":"Reusing a general request builder that always attaches tools for cached-context calls; forgetting that the cached context was created with its own system instruction/tools; Google tool-caching tutorials that warn against duplicating config.","solutions":["Remove the request-level systemInstruction/tools/toolConfig and rely on what was baked into the cache","Create the cached context with the system instruction and tools you need, then send only messages + cachedContent","Split your code path: separate cache-backed requests from regular requests","If tools differ per request, do not use cachedContent for those calls"],"exampleFix":"// before\nawait streamGoogle(model, { system, tools, messages, cachedContent: cacheName });\n// after\nawait streamGoogle(model, { messages, cachedContent: cacheName }); // system/tools live in the cache\n// or for per-request tools: create a cache per toolset, or drop cachedContent","handlingStrategy":"validation","validationCode":"function assertCacheCompatible(params: { system?: unknown; tools?: unknown; toolConfig?: unknown; cachedContent?: string }) {\n  if (!params.cachedContent) return;\n  const conflicts = [\n    params.system !== undefined && \"systemInstruction\",\n    params.tools !== undefined && \"tools\",\n    params.toolConfig !== undefined && \"toolConfig\",\n  ].filter(Boolean);\n  if (conflicts.length) throw new TypeError(`cachedContent cannot be combined with ${conflicts.join(\", \")}`);\n}","typeGuard":"function isCacheOnlyRequest(p: { system?: unknown; tools?: unknown; cachedContent?: string }): p is { cachedContent: string } {\n  return p.cachedContent !== undefined && p.system === undefined && p.tools === undefined;\n}","tryCatchPattern":"try {\n  await streamGoogle(model, params);\n} catch (err) {\n  if (err instanceof AIError.ValidationError && err.message.startsWith(\"cachedContent cannot be combined\")) {\n    const { system, tools, toolConfig, ...rest } = params;\n    return await streamGoogle(model, rest); // let the cache supply system/tools\n  }\n  throw err;\n}","preventionTips":["Structure your request builder so cache-backed requests take a distinct params shape without system/tools","Create caches that already include the systemInstruction and tools each call needs","Encode this constraint in your types (discriminated union: CacheRequest vs StandardRequest) so TS rejects the combination","Document in your codebase that Google cachedContent is mutually exclusive with request-level config"],"tags":["google","validation","cached-content","tools"],"backgroundTag":"incompatible-parameters","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}