can1357/oh-my-pi · error
Cache benchmark prefix template is missing its raw prefix pl
Error message
Cache benchmark prefix template is missing its raw prefix placeholder
What it means
renderCacheBenchmarkPrefix renders the cache prefix template with a placeholder token, then injects the caller's prefix bytes via a function replacer (so regex metacharacters in the prefix aren't expanded). It throws if the placeholder survived rendering — meaning the template failed to consume the raw prefix slot, so the caller's prefix bytes were never injected and the benchmark prefix would be wrong.
Source
Thrown at packages/coding-agent/src/cli/bench-cli.ts:436
}
function truncateUtf8(text: string, maxBytes: number): string {
const bytes = UTF8_ENCODER.encode(text);
const end = truncateUtf8ByteLength(bytes, maxBytes);
return end === bytes.byteLength ? text : UTF8_DECODER.decode(bytes.subarray(0, end));
}
function generatedCachePrefix(bytes: number): string {
return truncateUtf8(CACHE_PREFIX_CHUNK.repeat(Math.ceil(bytes / CACHE_PREFIX_CHUNK_BYTES)), bytes);
}
function renderCacheBenchmarkPrefix(prefix: string, namespace: string): string {
const rendered = prompt.render(cachePrefixTemplate, {
prefix: CACHE_PREFIX_PLACEHOLDER,
namespace,
});
if (!rendered.includes(CACHE_PREFIX_PLACEHOLDER)) {
throw new Error("Cache benchmark prefix template is missing its raw prefix placeholder");
}
// Render the static wrapper first, then inject caller bytes so prompt
// normalization cannot trim spaces or collapse blank lines in prefix files.
// Function replacer: a prefix containing `$&`/`$'`/`` $` `` must not be
// expanded as a string-replacement pattern.
return rendered.replace(CACHE_PREFIX_PLACEHOLDER, () => prefix);
}
async function resolveCachePrefix(
flags: BenchCommandArgs["flags"],
readTextFile: (path: string, maxBytes: number) => Promise<string>,
): Promise<string> {
const bytes = normalizePositiveInteger("cache-prefix-bytes", flags.cachePrefixBytes, DEFAULT_CACHE_PREFIX_BYTES);
const prefix = flags.cachePrefixFile
? await readTextFile(flags.cachePrefixFile, bytes)
: generatedCachePrefix(bytes);
return truncateUtf8(prefix, bytes);
}View on GitHub (pinned to 9690622007)
Solutions
- Restore the raw prefix placeholder token in the cache prefix template file.
- Verify the placeholder name matches CACHE_PREFIX_PLACEHOLDER exactly (no renaming/escaping).
- Re-run the benchmark after the template fix.
Example fix
// before (template)
You are a helpful assistant.
// after (template)
{{prefix}}
You are a helpful assistant. Defensive patterns
Strategy: validation
Validate before calling
const tpl = await Bun.file(cachePrefixPath).text();
if (!tpl.includes("{{prefix}}")) throw new Error("prefix template lost its placeholder"); Type guard
function templateHasPlaceholder(t: string, p: string): boolean {
return t.includes(p);
} Try / catch
try {
const prefix = stablePrefix(bytes, ns);
} catch (err) {
if (String(err).includes("missing its raw prefix placeholder")) {
logger.error("cache prefix template is broken; restore the placeholder token");
}
throw err;
} Prevention
- Add a unit test asserting the placeholder survives prompt.render
- Never hand-edit the placeholder token in the template
- Review template changes with the cache benchmark smoke run
When it happens
Trigger: Editing/misconfiguring the cache prefix prompt template so it no longer contains the CACHE_PREFIX_PLACEHOLDER, or prompt.render stripping the placeholder token.
Common situations: A contributor edits the cache prefix .md template and removes/renames the placeholder; a templating change that HTML-escapes or trims the token.
Related errors
- --cache is not supported for openai-codex-responses because
- Sloppy edit completed without a result.
- pr://${repo}/${parsed.number}/diff/${index} resolved to a mi
- Invalid issue:// URL: unexpected variant '${parsed.kind}'
- RPC chunk exceeded the transport limit
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/297f96a685b8f076.
Report an issue: GitHub.