{"record":{"id":"3d5f16e943c9a037","repo":"lobehub/lobehub","slug":"not-found-3d5f16","errorCode":"NOT_FOUND","errorMessage":"Knowledge base not found","messagePattern":"Knowledge base not found","errorType":"exception","errorClass":"TRPCError","httpStatus":404,"severity":"error","filePath":"apps/server/src/routers/lambda/file.ts","lineNumber":202,"sourceCode":"      // Resolve parentId if it's a slug\n      let resolvedParentId = input.parentId;\n      let parentVisibility: 'private' | 'public' | undefined;\n      if (input.parentId) {\n        const docBySlug = await ctx.documentModel.findBySlug(input.parentId);\n        if (docBySlug) {\n          resolvedParentId = docBySlug.id;\n          parentVisibility = docBySlug.visibility;\n        } else {\n          const docById = await ctx.documentModel.findById(input.parentId);\n          if (docById) parentVisibility = docById.visibility;\n        }\n      }\n\n      let knowledgeBaseVisibility: 'private' | 'public' | undefined;\n      if (ctx.workspaceId && input.knowledgeBaseId) {\n        const knowledgeBase = await ctx.knowledgeBaseModel.findById(input.knowledgeBaseId);\n        if (!knowledgeBase) {\n          throw new TRPCError({ code: 'NOT_FOUND', message: 'Knowledge base not found' });\n        }\n        knowledgeBaseVisibility = knowledgeBase.visibility;\n      }\n\n      // Visibility precedence (workspace mode only — personal mode ignores the\n      // column entirely):\n      //   1. A library upload always uses the knowledge base visibility.\n      //   2. Otherwise an explicit caller value wins.\n      //   3. Otherwise inherit the parent document's visibility so a file\n      //      uploaded inside a private folder stays private.\n      //   4. Otherwise default top-level uploads to 'private' so new content\n      //      starts in the creator's private space (mirrors the Pages spec).\n      const resolvedVisibility: 'private' | 'public' | undefined = ctx.workspaceId\n        ? (knowledgeBaseVisibility ?? input.visibility ?? parentVisibility ?? 'private')\n        : undefined;\n\n      let actualSize = input.size;\n      try {","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/lobehub/lobehub/blob/10f24d7ade75139093a9373b364f6bc91f3cd7db/apps/server/src/routers/lambda/file.ts#L184-L220","documentation":"Thrown by file.createFile (file.ts:202) when the upload is workspace-scoped (ctx.workspaceId set) and carries a knowledgeBaseId, but knowledgeBaseModel.findById(input.knowledgeBaseId) returns null. The knowledge base must exist before the upload's visibility-precedence logic can inherit its visibility. The check fires before any size validation or transaction.","triggerScenarios":"Uploading a file into a knowledge base that was deleted, belongs to a different workspace, or whose id is wrong/stale. The lookup is by id only, so an id from another workspace fails the same way.","commonSituations":"Knowledge base deleted while the upload dialog was open; id copied from another workspace; upload triggered from a cached KB picker after the KB was moved.","solutions":["Re-fetch the knowledge base list for the active workspace and use a current knowledgeBaseId.","If the upload does not target a knowledge base, omit knowledgeBaseId entirely rather than passing a stale id.","Drop the KB reference from the UI when the KB list no longer contains it."],"exampleFix":"// before\nawait trpc.file.createFile.mutate({ ..., knowledgeBaseId: staleKbId });\n// after\nconst kbs = await trpc.knowledgeBase.list.query();\nconst kb = kbs.find((k) => k.id === staleKbId);\nif (!kb) {\n  showToast('Select a knowledge base');\n  return;\n}\nawait trpc.file.createFile.mutate({ ..., knowledgeBaseId: kb.id });","handlingStrategy":"validation","validationCode":"const kbs = await trpc.knowledgeBase.list.query();\nif (!kbs.some((k) => k.id === knowledgeBaseId)) {\n  showToast('Select a valid knowledge base');\n  return;\n}\nawait trpc.file.createFile.mutate({ ..., knowledgeBaseId });","typeGuard":"function isKnowledgeBaseMissing(err: unknown): boolean {\n  return (\n    typeof err === 'object' &&\n    err !== null &&\n    (err as { data?: { code?: string } }).data?.code === 'NOT_FOUND'\n  );\n}","tryCatchPattern":"try {\n  await trpc.file.createFile.mutate({ ..., knowledgeBaseId });\n} catch (err) {\n  if (isTrpcCode(err, 'NOT_FOUND')) {\n    refreshKnowledgeBases();\n    return;\n  }\n  throw err;\n}","preventionTips":["Omit knowledgeBaseId when the upload is not targeting a KB rather than passing a stale id.","Re-fetch the KB list when the upload dialog opens.","Invalidate cached KB ids after a KB is deleted or moved."],"tags":["trpc","file","not-found","knowledge-base","upload"],"backgroundTag":null,"analyzedSha":"10f24d7ade75139093a9373b364f6bc91f3cd7db","analyzedAt":"2026-08-12T11:43:19.543Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}