can1357/oh-my-pi · error
replace_memory_files contains an invalid file entry
Error message
replace_memory_files contains an invalid file entry
What it means
Each entry of the `files` array in a `replace_memory_files` call must be a non-null object containing both `name` and `content`, the name must be one of the known sharpshooter memory filenames, and content must be a string. This error is thrown when either the structural check (missing name/content, null/primitive entry) or the value check (unknown name or non-string content) fails.
Source
Thrown at packages/coding-agent/src/sharpshooter/consolidate.ts:247
): ReplacementFile[] {
const toolCalls = content.filter(
(block): block is { type: "toolCall"; name: string; arguments: unknown } =>
typeof block === "object" && block !== null && "type" in block && block.type === "toolCall",
);
if (toolCalls.length !== 1 || toolCalls[0]?.name !== replaceMemoryFilesTool.name) {
throw new Error("sharpshooter consolidation must call replace_memory_files exactly once");
}
const args = toolCalls[0].arguments;
if (!args || typeof args !== "object" || !("files" in args) || !Array.isArray(args.files)) {
throw new Error("replace_memory_files requires a files array");
}
const seen = new Set<SharpshooterMemoryFile>();
const files: ReplacementFile[] = [];
for (const item of args.files) {
if (!item || typeof item !== "object" || !("name" in item) || !("content" in item)) {
throw new Error("replace_memory_files contains an invalid file entry");
}
const name = item.name;
const rawContent = item.content;
if (!isMemoryFileName(name) || typeof rawContent !== "string") {
throw new Error("replace_memory_files contains an invalid file entry");
}
if (seen.has(name)) throw new Error(`replace_memory_files contains duplicate ${name}`);
seen.add(name);
const redacted = redactSecrets(rawContent);
let lines = redacted.length > 0 ? 1 : 0;
for (let index = 0; index + 1 < redacted.length; index++) {
if (redacted.charCodeAt(index) === 10) lines += 1;
}
if (lines > SHARPSHOOTER_MAX_FILE_LINES) {
throw new Error(`${name} exceeds the ${SHARPSHOOTER_MAX_FILE_LINES}-line limit`);
}
files.push({ name, content: redacted });
}View on GitHub (pinned to 9690622007)
Solutions
- Use exactly the allowed memory file names for `name` (check SHARPSHOOTER_MEMORY_FILES / the tool description).
- Ensure every entry has both `name` (string) and `content` (string) keys.
- Regenerate the tool call with a stricter schema (enum on name, type string on content).
- Retry the run — this is model output, not caller input.
Example fix
// before
{ files: [{ name: "notes.md", content: 42 }] }
// after: allowed name, string content
{ files: [{ name: "AGENTS.md", content: "..." }] } Defensive patterns
Strategy: validation
Validate before calling
const valid = files.every(f => f && typeof f === "object" && "name" in f && "content" in f);
Type guard
const isReplacementFile = (x: unknown): x is { name: unknown; content: unknown } =>
typeof x === "object" && x !== null && "name" in x && "content" in x; Try / catch
try {
return parseReplacementFiles(call, currentFiles);
} catch (err) {
if (err instanceof Error && err.message.includes("invalid file entry")) {
return retryConsolidation();
}
throw err;
} Prevention
- Pin `name` to an enum in the tool schema.
- Require `content` to be type string in the schema.
- Test consolidation against weak models that emit malformed JSON.
When it happens
Trigger: An entry in `args.files` is null, a primitive, or missing `name`/`content` keys; or `name` is not one of SHARPSHOOTER_MEMORY_FILES; or `content` is a number/boolean/object instead of a string.
Common situations: Model inventing a new memory filename not in the allowed set; hallucinated entries with truncated or typed content (e.g. numeric line counts); null entries from malformed JSON streaming.
Related errors
- Validation failed for tool "${toolCall.name}":\n${errors}\n\
- replace_memory_files requires a files array
- Tool ${toolCall.name} not found
- anthropic-messages: ${data.summary}
- Schema contains a circular object graph — cannot enforce str
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/29d550d684a72d97.
Report an issue: GitHub.