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

  1. Only pass cachedContent when a non-empty value exists: omit the field instead of sending ""
  2. Fix the config source so unset values become undefined, not ""
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/61403b4ac098baec. Report an issue: GitHub.