TencentCloud/TencentDB-Agent-Memory · error
File not found: ${key}
Error message
File not found: ${key} What it means
readFileOrThrow is the strict variant of readFile: readFile returns null for a missing object, while readFileOrThrow converts that null into a thrown Error with the key in the message. It exists so callers that require the file can avoid null-check boilerplate.
Source
Thrown at MemoryCore/src/core/storage/adapter.ts:99
return new StorageAdapter(new ScopedStorageBackend(base.getBackend(), prefix));
}
export class StorageAdapter {
constructor(private backend: IStorageBackend) {}
get type() { return this.backend.type; }
// ── fs.readFile replacement ──
async readFile(key: string): Promise<string | null> {
const obj = await this.backend.getObject(key);
if (!obj) return null;
return obj.content.toString("utf-8");
}
async readFileOrThrow(key: string): Promise<string> {
const content = await this.readFile(key);
if (content === null) throw new Error(`File not found: ${key}`);
return content;
}
async readFileBuffer(key: string): Promise<Buffer | null> {
const obj = await this.backend.getObject(key);
if (!obj) return null;
return obj.content;
}
// ── fs.writeFile replacement ──
async writeFile(key: string, content: string | Buffer): Promise<void> {
return this.backend.putObject(key, content);
}
// ── fs.appendFile replacement — atomic via backend.appendObject (CR-1 fix) ──
/**View on GitHub (pinned to 3efcd317b8)
Solutions
- Check existence first with adapter.exists(key) or use readFile and handle null
- Fix the key — verify exact spelling/case and that it is relative to the adapter's scope
- Create/initialize the object (write a default) on first access if absence is expected
- Handle the error and fall back to a default value in the caller
Example fix
// before
const cfg = await adapter.readFileOrThrow('config.json');
// after
const cfg = (await adapter.readFile('config.json')) ?? JSON.stringify(DEFAULT_CONFIG); Defensive patterns
Strategy: try-catch
Validate before calling
if (!(await adapter.exists(key))) {
return DEFAULT_CONTENT; // or throw a domain-level NotFound
} Try / catch
try {
content = await adapter.readFileOrThrow(key);
} catch (e) {
if (String(e.message).startsWith('File not found:')) {
content = await initializeDefault(key); // create default on first access
} else throw e;
} Prevention
- Prefer readFile (null-returning) when absence is an expected state
- Use readFileOrThrow only for files that must exist (invariants/config)
- Verify key spelling, case, and scope prefix when debugging
- Write defaults at first boot so required keys always exist
When it happens
Trigger: Calling readFileOrThrow(key) when no object exists at that (already prefixed) key in the storage backend.
Common situations: Reading a config or state file before it was ever written; a typo or case mismatch in the key; the object was deleted by another process; using the raw key without the adapter's scoping prefix on a raw backend.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Source not found: ${sourceKey}
- STORAGE_NOT_FOUND
- Generation log object key exceeds COS limit
- Invalid generation log key
- Invalid generation log cursor
AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01).
Data as JSON: /api/errors/89f8494318308a85.
Report an issue: GitHub.