{"record":{"id":"8b6ac07196fd2383","repo":"paperclipai/paperclip","slug":"select-a-company-to-upload-images-8b6ac0","errorCode":null,"errorMessage":"Select a company to upload images","messagePattern":"Select a company to upload images","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/pages/AgentDetail.production.tsx","lineNumber":2434,"sourceCode":"    },\n    onError: () => setAwaitingRefresh(false),\n  });\n\n  const deleteFile = useMutation({\n    mutationFn: (relativePath: string) => agentsApi.deleteInstructionsFile(agent.id, relativePath, companyId),\n    onMutate: () => setAwaitingRefresh(true),\n    onSuccess: (_, relativePath) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.agents.instructionsBundle(agent.id) });\n      queryClient.removeQueries({ queryKey: queryKeys.agents.instructionsFile(agent.id, relativePath) });\n      queryClient.invalidateQueries({ queryKey: queryKeys.agents.detail(agent.id) });\n      queryClient.invalidateQueries({ queryKey: queryKeys.agents.detail(agent.urlKey) });\n    },\n    onError: () => setAwaitingRefresh(false),\n  });\n\n  const uploadMarkdownImage = useMutation({\n    mutationFn: async ({ file, namespace }: { file: File; namespace: string }) => {\n      if (!selectedCompanyId) throw new Error(\"Select a company to upload images\");\n      return assetsApi.uploadImage(selectedCompanyId, file, namespace);\n    },\n  });\n\n  useEffect(() => {\n    if (!bundle) return;\n    if (!bundleMatchesDraft) {\n      if (selectedFile !== currentEntryFile) setSelectedFile(currentEntryFile);\n      return;\n    }\n    const availablePaths = bundle.files.map((file) => file.path);\n    if (availablePaths.length === 0) {\n      if (selectedFile !== bundle.entryFile) setSelectedFile(bundle.entryFile);\n      return;\n    }\n    if (!availablePaths.includes(selectedFile) && selectedFile !== currentEntryFile && !pendingFiles.includes(selectedFile)) {\n      setSelectedFile(availablePaths.includes(bundle.entryFile) ? bundle.entryFile : availablePaths[0]!);\n    }","sourceCodeStart":2416,"sourceCodeEnd":2452,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/pages/AgentDetail.production.tsx#L2416-L2452","documentation":"The image-upload mutation in AgentDetail requires an active company selection because assets are uploaded to a company-scoped assets API endpoint. If the user has not selected a company (selectedCompanyId is null/undefined), the mutation throws this error instead of calling assetsApi.uploadImage. It is a guard against an impossible/ambiguous request rather than an API failure.","triggerScenarios":"Invoking uploadMarkdownImage.mutate({ file, namespace }) (e.g. pasting or dropping an image into the markdown editor) while no company is selected in the company selector.","commonSituations":"Landing on the agent detail page before the company context loads; the company selector was never set; a deep link that bypasses company selection; company data still fetching so the id is briefly null when the user pastes an image.","solutions":["Select a company in the company picker before uploading/pasting images.","Gate the upload affordance (paste/drop handler, toolbar button) on Boolean(selectedCompanyId) so it is disabled without a company.","Ensure the company selection context is hydrated before rendering the editor.","If the page is inherently company-scoped, redirect to company selection when selectedCompanyId is missing."],"exampleFix":"// before\nif (!selectedCompanyId) throw new Error(\"Select a company to upload images\");\nreturn assetsApi.uploadImage(selectedCompanyId, file, namespace);\n// after (caller-side guard)\nif (!selectedCompanyId) {\n  toast.info(\"Select a company to upload images\");\n  return;\n}\nawait uploadMarkdownImage.mutateAsync({ file, namespace });","handlingStrategy":"validation","validationCode":"if (!selectedCompanyId) {\n  toast.info(\"Select a company to upload images\");\n  return;\n}","typeGuard":"const canUpload = (id: string | null | undefined): id is string => typeof id === \"string\" && id.length > 0;","tryCatchPattern":"try {\n  await uploadMarkdownImage.mutateAsync({ file, namespace });\n} catch (e) {\n  if (e.message === \"Select a company to upload images\") toast.info(e.message);\n  else toast.error(\"Image upload failed\");\n}","preventionTips":["Disable paste/drop image handling and upload buttons until a company is selected.","Block editor interactions behind a company-selected gate on company-scoped pages.","Show the company picker prominently and persist the last selection."],"tags":["ui","company-scope","upload","missing-selection"],"backgroundTag":"missing-required-argument","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}