{"record":{"id":"6827c0a853bcb020","repo":"mastra-ai/mastra","slug":"filesystemstorage-resourceid-must-not-be-empty","errorCode":null,"errorMessage":"[FilesystemStorage] resourceId must not be empty.","messagePattern":"\\[FilesystemStorage\\] resourceId must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/storage/domains/filesystem/base.ts","lineNumber":44,"sourceCode":"    uniqueIndexes: [\n      {\n        name: 'filesystem_snapshots_resource_thread_unique',\n        columns: ['resource_id', 'thread_id'],\n      },\n    ],\n  },\n];\n\ninterface FilesystemSnapshotDbRow extends Record<string, unknown> {\n  id: string;\n  resource_id: string;\n  thread_id: string;\n  files: FilesystemFile[];\n  captured_at: Date;\n}\n\nfunction assertIdentifier(value: string, label: string): void {\n  if (!value.trim()) throw new Error(`[FilesystemStorage] ${label} must not be empty.`);\n}\n\nfunction assertRelativePath(value: string): void {\n  if (\n    !value ||\n    value.startsWith('/') ||\n    value.split('/').some(segment => !segment || segment === '.' || segment === '..')\n  ) {\n    throw new Error('[FilesystemStorage] path must be a non-empty relative path.');\n  }\n}\n\nfunction assertScope(args: { resourceId: string; threadId: string }): void {\n  assertIdentifier(args.resourceId, 'resourceId');\n  assertIdentifier(args.threadId, 'threadId');\n}\n\nfunction validateFiles(files: FilesystemFile[]): void {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/storage/domains/filesystem/base.ts#L26-L62","documentation":"FilesystemStorage's assertIdentifier rejects empty/whitespace identifiers. When assertScope validates a call's resourceId and finds it empty, it throws '[FilesystemStorage] resourceId must not be empty.' resourceId is the primary partition key for stored files, so the domain refuses to proceed.","triggerScenarios":"Any FilesystemStorage domain method that runs assertScope with args.resourceId set to '' or whitespace — e.g. listing/saving files without supplying the resource ID.","commonSituations":"Caller built the args object conditionally and omitted resourceId; an upstream object spread produced undefined coerced in as empty; refactoring renamed the field so the value no longer lands in resourceId.","solutions":["Pass a non-empty resourceId string to the storage call","Validate the resourceId at the API boundary before calling storage","Fix field naming/spread so the resource ID actually reaches args.resourceId","Trim user input and reject blanks early"],"exampleFix":"// before\nawait storage.list({ resourceId: input.resourceId ?? '', threadId });\n// after\nif (!input.resourceId?.trim()) throw new ValidationError('resourceId is required');\nawait storage.list({ resourceId: input.resourceId, threadId });","handlingStrategy":"validation","validationCode":"function requireResourceId(v: string | undefined): string {\n  const id = (v ?? '').trim();\n  if (!id) throw new Error('resourceId is required and must not be blank');\n  return id;\n}","typeGuard":"function hasResourceId(args: { resourceId?: string; threadId: string }): args is { resourceId: string; threadId: string } {\n  return typeof args.resourceId === 'string' && args.resourceId.trim().length > 0;\n}","tryCatchPattern":"try {\n  await storage.call(args);\n} catch (e) {\n  if (e instanceof Error && e.message === '[FilesystemStorage] resourceId must not be empty.') {\n    throw new BadRequest('resourceId is required');\n  }\n  throw e;\n}","preventionTips":["Validate resourceId at the API/controller layer before storage calls","Avoid ?? '' fallbacks that convert missing IDs to blanks","Trim and reject whitespace-only IDs","Keep resourceId and threadId supplied together via a typed args object"],"tags":["validation","storage","filesystem"],"backgroundTag":"empty-identifier","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}