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

  1. Verify the object exists under companyId/objectKey before calling getObject, or handle a not-found case upstream.
  2. Check the companyId prefix and objectKey spelling against what was written by putObject.
  3. If using an S3 emulator, confirm it throws NoSuchKey instead of returning an empty body, or pre-stat the object.
  4. 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

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


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/e45c759cf68dcc29. Report an issue: GitHub.