NousResearch/hermes-agent · warning · Error

Could not open preview target: ${item.target}

Error message

Could not open preview target: ${item.target}

What it means

Thrown by PreviewStatusRow in the desktop composer's status stack when the user clicks to open a detected artifact and normalizeOrLocalPreviewTarget fails to resolve item.target (with item.cwd) into anything previewable. The throw is caught by the row's toggle flow and typically surfaced as a failed open action; it distinguishes 'target unresolvable' from 'preview pane open failed'.

Source

Thrown at apps/desktop/src/app/chat/composer/status-stack/preview-row.tsx:33

interface PreviewStatusRowProps {
  item: PreviewArtifact
  onDismiss: (id: string) => void
}

/** One detected artifact, single line, always visible: filename + open + close. */
export const PreviewStatusRow = memo(function PreviewStatusRow({ item, onDismiss }: PreviewStatusRowProps) {
  const { t } = useI18n()
  const openSources = useStore($previewTabSources)
  const [opening, setOpening] = useState(false)
  // A tab open IS a pane in the tree now, so its presence is the whole answer.
  const isOpen = openSources.includes(item.target)

  const resolveTarget = async () => {
    const target = await normalizeOrLocalPreviewTarget(item.target, item.cwd || undefined)

    if (!target) {
      throw new Error(`Could not open preview target: ${item.target}`)
    }

    return target
  }

  const togglePreview = async () => {
    if (opening) {
      return
    }

    if (isOpen) {
      closePreviewForSource(item.target)

      return
    }

    setOpening(true)

View on GitHub (pinned to c896c09c42)

Solutions

  1. Confirm the artifact file still exists at the resolved location; if it was cleaned, re-run the generating command.
  2. Ensure item.cwd is populated so relative targets resolve; if the detector emits bare filenames, make it emit absolute paths.
  3. For remote backends, preview only targets reachable from the client (local mount or http URL).
  4. As a developer: catch this error in togglePreview and show a toast with item.target so users see which artifact failed.

Example fix

// before
const resolveTarget = async () => {
  const target = await normalizeOrLocalPreviewTarget(item.target, item.cwd || undefined)
  if (!target) {
    throw new Error(`Could not open preview target: ${item.target}`)
  }
  return target
}

// after — fall back to an absolute-path attempt before giving up
const resolveTarget = async () => {
  const target = (await normalizeOrLocalPreviewTarget(item.target, item.cwd || undefined))
    ?? (await normalizeOrLocalPreviewTarget(item.absolutePath ?? item.target, undefined))
  if (!target) {
    throw new Error(`Could not open preview target: ${item.target}`)
  }
  return target
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!item.target || !(item.target.startsWith('/') || /^https?:/.test(item.target) || item.cwd)) {
  // cannot resolve a bare target without a cwd — mark the row unopenable
  return null
}

Type guard

interface PreviewItem { target: string; cwd?: string }
const isResolvablePreviewItem = (i: PreviewItem): boolean =>
  i.target.startsWith('/') || /^https?:/.test(i.target) || Boolean(i.cwd)

Try / catch

const togglePreview = async () => {
  if (opening) return
  try {
    const target = await resolveTarget()
    openPreview(target, 'status-row')
  } catch (error) {
    notifyError(error, `Preview unavailable for ${item.target}`)
  } finally {
    setOpening(false)
  }
}

Prevention

When it happens

Trigger: Clicking the open/toggle control on a preview status row whose item.target is a relative path that cannot be anchored (item.cwd missing or stale), a path to a file that was deleted since detection, or a remote/SSH-only path on a backend the local resolver cannot reach.

Common situations: Artifacts detected from terminal output in remote sessions (paths exist only on the backend), build artifacts cleaned between detection and click, cwd-relative targets after the session's working directory changed.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/db3e157d4c2116f1. Report an issue: GitHub.