{"record":{"id":"e561ca65bbddce7f","repo":"paperclipai/paperclip","slug":"no-selection-to-anchor-to","errorCode":null,"errorMessage":"No selection to anchor to.","messagePattern":"No selection to anchor to\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/hooks/useDocumentAnnotationMutations.ts","lineNumber":46,"sourceCode":"    id: session?.user?.id ?? null,\n    name: session?.user?.name?.trim() || session?.user?.email?.trim() || \"You\",\n    image: session?.user?.image ?? null,\n  }), [session]);\n  const queryKey = useMemo(() => options.target.kind === \"routine\"\n    ? queryKeys.routines.documentAnnotations(options.target.routineId, options.target.documentKey, \"all\")\n    : options.target.kind === \"case\"\n      ? queryKeys.cases.documentAnnotations(options.target.caseId, options.target.documentKey, \"all\")\n      : queryKeys.issues.documentAnnotations(options.target.issueId, options.target.documentKey, \"all\"), [options.target]);\n  const invalidateAll = useCallback(() => queryClient.invalidateQueries({\n    predicate: (query) => Array.isArray(query.queryKey)\n      && query.queryKey[1] === \"document-annotations\"\n      && query.queryKey[2] === (options.target.kind === \"issue\" ? options.target.issueId : options.target.kind === \"case\" ? options.target.caseId : options.target.routineId)\n      && query.queryKey[3] === options.target.documentKey,\n  }), [options.target, queryClient]);\n\n  const createThread = useMutation({\n    mutationFn: async (body: string) => {\n      if (!options.pendingAnchor) throw new Error(\"No selection to anchor to.\");\n      if (!options.baseRevisionId) throw new Error(\"Document has no revision yet.\");\n      return documentAnnotationsApi.createForTarget(options.target, {\n        baseRevisionId: options.baseRevisionId,\n        baseRevisionNumber: options.baseRevisionNumber,\n        selector: options.pendingAnchor.selector,\n        body,\n      });\n    },\n    onMutate: async (body) => {\n      if (!options.pendingAnchor || !options.baseRevisionId) return undefined;\n      setMutationError(null);\n      await queryClient.cancelQueries({ queryKey });\n      const previous = queryClient.getQueryData<DocumentAnnotationThreadWithComments[]>(queryKey);\n      const optimistic = buildOptimisticThread(body, options, currentUser);\n      queryClient.setQueryData<DocumentAnnotationThreadWithComments[]>(queryKey, (current) => [...(current ?? []), optimistic]);\n      options.onFocusThread(optimistic.id);\n      return { previous, optimisticId: optimistic.id };\n    },","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/ui/src/hooks/useDocumentAnnotationMutations.ts#L28-L64","documentation":"UI annotation mutation precondition: createThread was invoked with no active text selection to anchor a new comment thread to. The guard fails fast in the mutationFn before any API call; the fix is UI-side — require a selection before enabling the annotate action.","triggerScenarios":"Thrown at ui/src/hooks/useDocumentAnnotationMutations.ts:46 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Select the text or region in the document before creating the annotation."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}