paperclipai/paperclip · error · Error
Object not found.
Error message
Object not found.
What it means
Thrown by s3BodyToBuffer when the response body from a storage getObject call is falsy (null/undefined/empty). This signals that the underlying S3-compatible GET or local read returned no body, which the helper interprets as the requested object not existing in the bucket/directory.
Source
Thrown at cli/src/commands/worktree.ts:319
const parts = normalized.split("/").filter((part) => part.length > 0);
if (parts.length === 0 || parts.some((part) => part === "." || part === "..")) {
throw new Error("Invalid object key.");
}
return parts.join("/");
}
function resolveLocalStoragePath(baseDir: string, objectKey: string): string {
const resolved = path.resolve(baseDir, normalizeStorageObjectKey(objectKey));
const root = path.resolve(baseDir);
if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {
throw new Error("Invalid object key path.");
}
return resolved;
}
async function s3BodyToBuffer(body: unknown): Promise<Buffer> {
if (!body) {
throw new Error("Object not found.");
}
if (Buffer.isBuffer(body)) {
return body;
}
if (body instanceof Readable) {
return await streamToBuffer(body);
}
const candidate = body as {
transformToWebStream?: () => ReadableStream<Uint8Array>;
arrayBuffer?: () => Promise<ArrayBuffer>;
};
if (typeof candidate.transformToWebStream === "function") {
const webStream = candidate.transformToWebStream();
const reader = webStream.getReader();
const chunks: Uint8Array[] = [];
while (true) {
const { done, value } = await reader.read();View on GitHub (pinned to 67001ec6eb)
Solutions
- Verify the object exists under companyId/objectKey before calling getObject, or handle a not-found case upstream.
- Check the companyId prefix and objectKey spelling against what was written by putObject.
- If using an S3 emulator, confirm it throws NoSuchKey instead of returning an empty body, or pre-stat the object.
- Wrap getObject in try/catch and map a missing-object case to an application-level 404 rather than crashing.
Example fix
// before
const buf = await storage.getObject(companyId, key);
// after
try {
const buf = await storage.getObject(companyId, key);
} catch (e) {
if (e.message === 'Object not found.') return null;
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
async function objectExists(storage: ConfiguredStorage, companyId: string, key: string): Promise<boolean> {
try { await storage.getObject(companyId, key); return true; }
catch (e) { return !(e instanceof Error && e.message === 'Object not found.'); }
} Type guard
function hasBody(body: unknown): body is NonNullable<unknown> {
return body != null;
} Try / catch
try {
const buf = await storage.getObject(companyId, key);
} catch (e) {
if (e instanceof Error && e.message === 'Object not found.') return null;
throw e;
} Prevention
- Existence-check objects before get when feasible.
- Map 'Object not found.' to an application-level 404 rather than crashing.
- Verify companyId/objectKey spelling against the write path.
When it happens
Trigger: Calling ConfiguredStorage.getObject for a companyId/objectKey combination where no object exists; the S3 SDK returns an empty/undefined Body on a 404 that was not surfaced as NoSuchKey; a local_disk read where fsPromises.readFile returned an empty buffer unexpectedly; mocking the S3 client without returning a Body field.
Common situations: Object was deleted between listing and get; companyId prefix mismatch causing lookup in wrong partition; test fixtures missing the expected file; S3-compatible emulator (MinIO, LocalStack) returning a non-standard empty body on missing keys.
Related errors
- Invalid object key path.
- Unsupported storage response body.
- Could not locate local Paperclip skills directory. Expected
- Export output path ${root} exists and is not a directory.
- Export output directory ${root} already contains files. Re-r
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/e45c759cf68dcc29.
Report an issue: GitHub.