can1357/oh-my-pi · error · AIError.ValidationError
cachedContent must not be blank
Error message
cachedContent must not be blank
What it means
buildGoogleGenerateContentParams validates options.cachedContent and throws AIError.ValidationError when it is whitespace-only. cachedContent must be a valid Google resource name referencing a cached context; a blank string can never be valid, so the library fails fast client-side.
Source
Thrown at packages/ai/src/providers/google-shared.ts:883
cfg.thinkingLevel = thinking.level as ThinkingLevel;
} else if (thinking.budgetTokens !== undefined) {
cfg.thinkingBudget = thinking.budgetTokens;
}
config.thinkingConfig = cfg;
}
if (options.signal) {
if (options.signal.aborted) {
throw new AIError.AbortError("Request aborted");
}
config.abortSignal = options.signal;
}
if (options.cachedContent !== undefined) {
// Blank names are never valid resource references; anything else stays
// opaque so we do not invent format/model/project checks here.
if (options.cachedContent.trim().length === 0) {
throw new AIError.ValidationError("cachedContent must not be blank");
}
const incompatibleFields = [
config.systemInstruction !== undefined && "systemInstruction",
config.tools !== undefined && "tools",
config.toolConfig !== undefined && "toolConfig",
].filter((field): field is string => Boolean(field));
if (incompatibleFields.length > 0) {
throw new AIError.ValidationError(
`cachedContent cannot be combined with request-level ${incompatibleFields.join(", ")}`,
);
}
config.cachedContent = options.cachedContent;
}
return {
model: model.id,
contents,
config,View on GitHub (pinned to 9690622007)
Solutions
- Only pass cachedContent when a non-empty value exists: omit the field instead of sending ""
- Fix the config source so unset values become undefined, not ""
- Trim and validate the cached context name before constructing options
Example fix
// before
const params = { cachedContent: process.env.GOOGLE_CACHED_CONTENT ?? "" };
await streamGoogle(model, params);
// after
const cachedContent = process.env.GOOGLE_CACHED_CONTENT?.trim() || undefined;
await streamGoogle(model, { ...baseParams, cachedContent }); Defensive patterns
Strategy: validation
Validate before calling
function requireCachedContent(name: string | undefined): string | undefined {
if (name === undefined) return undefined;
const trimmed = name.trim();
if (!trimmed) throw new TypeError("cachedContent configured but blank — unset it or provide a valid resource name");
return trimmed;
} Type guard
function isNonBlank(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;
} Try / catch
try {
await streamGoogle(model, { ...params, cachedContent });
} catch (err) {
if (err instanceof AIError.ValidationError && err.message.includes("cachedContent")) {
logger.warn("dropping blank cachedContent");
return await streamGoogle(model, params); // retry without caching
}
throw err;
} Prevention
- Coalesce empty env vars / config strings to undefined before building request options
- Validate config at startup: a configured-but-blank cache name should fail fast in CI, not at request time
- Trim and sanity-check resource names (projects/.../cachedContents/...) when loading from config
- Omit optional fields entirely instead of passing empty strings
When it happens
Trigger: Passing cachedContent: "" or " " (e.g. from an empty config field or env var that defaults to empty string) into the Google request options.
Common situations: Config/env var like GOOGLE_CACHED_CONTENT unset but read as empty string instead of undefined; UI form field left blank; template default interpolated as empty.
Related errors
- cachedContent cannot be combined with request-level ${incomp
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains a provider id wit
- ${name} path does not exist: ${trimmed}
- Anthropic thinking budget requires max_tokens greater than $
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/61403b4ac098baec.
Report an issue: GitHub.