{"record":{"id":"76c4dd207919c7e6","repo":"different-ai/openwork","slug":"urls-open-in-browser-tabs","errorCode":null,"errorMessage":"URLs open in browser tabs.","messagePattern":"URLs open in browser tabs\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/app/src/react-app/domains/session/artifacts/artifact-panel.tsx","lineNumber":128,"sourceCode":"  const workspaceName = workspaceRoot.split(/[/\\\\]/).filter(Boolean).pop() ?? \"Workspace\";\n\n  const openWorkspaceFile = (entry: { path: string; size: number; mtimeMs: number }) => {\n    const nextTarget = openTargetFromWorkspaceFile(entry.path, { size: entry.size, updatedAt: entry.mtimeMs });\n    if (!nextTarget) return;\n    usePanelTabStore.getState().openTab(sessionId, {\n      id: nextTarget.id,\n      type: \"artifact\",\n      label: nextTarget.name,\n      preview: nextTarget.preview,\n      target: nextTarget,\n    });\n  };\n\n  const { data, error, isError, isLoading } = useQuery<ArtifactQueryState>({\n    queryKey: [\"artifact-panel\", workspaceId, target.id, target.updatedAt ?? null] as const,\n    queryFn: async () => {\n      if (target.kind === \"url\") {\n        throw new Error(\"URLs open in browser tabs.\");\n      }\n      else if (target.exists === false) {\n        throw new Error(\"File not found in this workspace.\");\n      }\n\n      if (isTextContent(target)) {\n        const result = await client.readWorkspaceFile(workspaceId, target.value);\n\n        return { kind: \"text\", data: result.content, updatedAt: result.updatedAt ?? null };\n      }\n\n      const result = await client.downloadWorkspaceFile(workspaceId, target.value);\n\n      return { kind: \"binary\", data: result.data, contentType: result.contentType, updatedAt: target.updatedAt ?? null };\n    },\n    refetchOnReconnect: false,\n    refetchOnWindowFocus: false,\n    staleTime: Infinity,","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/session/artifacts/artifact-panel.tsx#L110-L146","documentation":"The artifact panel's query function only loads workspace file artifacts; URL artifacts are not viewable in the panel and are meant to be opened in the browser. The queryFn intentionally throws this plain Error so React Query surfaces an error state instead of attempting to read a URL as a file.","triggerScenarios":"ArtifactPanelView's useQuery queryFn is invoked with target.kind === \"url\" — i.e. the panel is asked to render an artifact whose target is a URL.","commonSituations":"Agent produced a URL artifact and the UI routed it to the artifact panel; user clicked an artifact entry of kind url; regression in artifact routing that no longer opens URLs in a browser tab.","solutions":["Open URL artifacts in a browser tab (window.open) instead of routing them to the artifact panel.","Filter or disable URL artifacts upstream so the panel is only opened for file targets.","Render a friendly 'open in browser' affordance for kind === \"url\" rather than letting the error state show.","If this is unexpected, check the artifact target typing — target.kind should be \"file\" for panel viewing."],"exampleFix":"// before\nopenArtifact(target); // panel handles all kinds\n// after\nif (target.kind === \"url\") window.open(target.value, \"_blank\");\nelse openArtifact(target);","handlingStrategy":"type-guard","validationCode":"if (target.kind === \"url\") {\n  window.open(target.value, \"_blank\");\n  return;\n}","typeGuard":"function isFileTarget(target: ArtifactTarget): target is ArtifactTarget & { kind: \"file\" } {\n  return target.kind === \"file\";\n}","tryCatchPattern":"const { data, isError, error } = useQuery({ queryKey: [...], queryFn });\nif (isError) {\n  if (error.message === \"URLs open in browser tabs.\") return <OpenInBrowserLink target={target} />;\n  return <ErrorState message={error.message} />;\n}","preventionTips":["Route url-kind artifacts to a browser open action, never to the panel query.","Narrow target.kind before mounting the panel component.","Test artifact routing for every artifact kind the agent can emit."],"tags":["react-query","ui","artifacts","intentional-error"],"backgroundTag":"unsupported-artifact-kind","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}