{"record":{"id":"e45c759cf68dcc29","repo":"paperclipai/paperclip","slug":"object-not-found","errorCode":null,"errorMessage":"Object not found.","messagePattern":"Object not found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/worktree.ts","lineNumber":319,"sourceCode":"  const parts = normalized.split(\"/\").filter((part) => part.length > 0);\n  if (parts.length === 0 || parts.some((part) => part === \".\" || part === \"..\")) {\n    throw new Error(\"Invalid object key.\");\n  }\n  return parts.join(\"/\");\n}\n\nfunction resolveLocalStoragePath(baseDir: string, objectKey: string): string {\n  const resolved = path.resolve(baseDir, normalizeStorageObjectKey(objectKey));\n  const root = path.resolve(baseDir);\n  if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {\n    throw new Error(\"Invalid object key path.\");\n  }\n  return resolved;\n}\n\nasync function s3BodyToBuffer(body: unknown): Promise<Buffer> {\n  if (!body) {\n    throw new Error(\"Object not found.\");\n  }\n  if (Buffer.isBuffer(body)) {\n    return body;\n  }\n  if (body instanceof Readable) {\n    return await streamToBuffer(body);\n  }\n\n  const candidate = body as {\n    transformToWebStream?: () => ReadableStream<Uint8Array>;\n    arrayBuffer?: () => Promise<ArrayBuffer>;\n  };\n  if (typeof candidate.transformToWebStream === \"function\") {\n    const webStream = candidate.transformToWebStream();\n    const reader = webStream.getReader();\n    const chunks: Uint8Array[] = [];\n    while (true) {\n      const { done, value } = await reader.read();","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/worktree.ts#L301-L337","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst buf = await storage.getObject(companyId, key);\n// after\ntry {\n  const buf = await storage.getObject(companyId, key);\n} catch (e) {\n  if (e.message === 'Object not found.') return null;\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"async function objectExists(storage: ConfiguredStorage, companyId: string, key: string): Promise<boolean> {\n  try { await storage.getObject(companyId, key); return true; }\n  catch (e) { return !(e instanceof Error && e.message === 'Object not found.'); }\n}","typeGuard":"function hasBody(body: unknown): body is NonNullable<unknown> {\n  return body != null;\n}","tryCatchPattern":"try {\n  const buf = await storage.getObject(companyId, key);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Object not found.') return null;\n  throw e;\n}","preventionTips":["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."],"tags":["storage","s3","object-not-found","filesystem"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}