{"record":{"id":"dda10fc44b869477","repo":"hcengineering/platform","slug":"no-such-storage-key","errorCode":null,"errorMessage":"No such storage key","messagePattern":"No such storage key","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"server/front/src/index.ts","lineNumber":557,"sourceCode":"              uuid,\n              workspace: wsIds.uuid\n            })\n          }\n        } catch (error: any) {\n          if (error instanceof PlatformError && error.status.code === platform.status.Unauthorized) {\n            res.status(401).send()\n            return\n          }\n          if (\n            error?.code === 'NoSuchKey' ||\n            error?.code === 'NotFound' ||\n            error?.message === 'No such key' ||\n            error?.Code === 'NoSuchKey'\n          ) {\n            ctx.error('No such storage key', {\n              file: req.query.file\n            })\n            res.status(404).send()\n            return\n          } else {\n            ctx.error('error-handle-files', { error })\n          }\n          res.status(500).send()\n        }\n      },\n      { url: req.path, query: req.query }\n    )\n  }\n\n  app.get('/files', (req, res) => {\n    void filesHandler(req, res)\n  })\n\n  app.head('/files/*', (req, res) => {\n    void filesHandler(req, res)\n  })","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/front/src/index.ts#L539-L575","documentation":"During file streaming in the files handler, storage errors whose message is 'No such key' or whose S3 error Code is 'NoSuchKey' are caught and surfaced as HTTP 404 with log 'No such storage key'. It is the mid-stream variant of error 905: the object disappeared or was never present when the actual read happened.","triggerScenarios":"Streaming a stored blob raises an error with message 'No such key' or Code 'NoSuchKey' — object deleted between stat and read, wrong key, or bucket inconsistency.","commonSituations":"Lifecycle/expiry policies deleting objects; concurrent deletion while downloading; cross-region/bucket replication lag; requesting keys from the wrong bucket.","solutions":["Confirm the object key exists in the configured bucket (aws s3 ls / mc stat).","Check bucket lifecycle/expiration rules that may auto-delete objects.","Re-upload the missing object and retry the download.","Verify the storage adapter points at the intended bucket/region."],"exampleFix":"// before\nconst stream = await adapter.stream(ctx, wsIds, uuid)\n// after\ntry {\n  const stream = await adapter.stream(ctx, wsIds, uuid)\n} catch (e) {\n  if (e.Code === 'NoSuchKey') await reuploadAndRetry(uuid)\n  else throw e\n}","handlingStrategy":"retry","validationCode":"async function ensureKeyExists(bucket: string, key: string): Promise<void> {\n  const head = await s3.send(new HeadObjectCommand({ Bucket: bucket, Key: key }))\n  if (head.$metadata.httpStatusCode !== 200) throw new Error(`missing object: ${key}`)\n}","typeGuard":"function isNoSuchKey(err: unknown): err is { Code: 'NoSuchKey'; message?: string } {\n  return typeof err === 'object' && err !== null &&\n    ((err as any).Code === 'NoSuchKey' || (err as any).message === 'No such key')\n}","tryCatchPattern":"try {\n  return await streamFile(uuid)\n} catch (err) {\n  if (isNoSuchKey(err)) {\n    await reuploadFile(uuid) // restore then retry once\n    return await streamFile(uuid)\n  }\n  throw err\n}","preventionTips":["Review bucket lifecycle/expiry rules so needed blobs are not auto-deleted.","Avoid deleting objects while downloads may still reference them (use soft delete).","Verify bucket/region configuration on the storage adapter after migrations."],"tags":["http-404","s3","storage"],"backgroundTag":"s3-nosuchkey","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}