stablyai/orca · error · Error

Unable to read markdown

Error message

Unable to read markdown

What it means

Thrown in readMarkdownTab() when the on-disk fallback (files.read) fails after markdown.readTab returned a recoverable failure (renderer_unavailable). The mobile client first tries markdown.readTab (rich rendering via desktop renderer); if that fails with renderer_unavailable on a headless host, it falls back to files.read for raw content. This error means both paths failed — the file itself could not be read.

Source

Thrown at mobile/app/h/[hostId]/session/[worktreeId].tsx:1863

              baseVersion: result.version,
              isDirty: false,
              editable: result.editable === true,
              stale: result.isDirty,
              readOnlyReason: result.readOnlyReason
            })
          )
          return
        }
        if (!shouldReadMarkdownFromDiskAfterReadTabFailure(response as RpcFailure)) {
          throw new Error((response as RpcFailure).error.message)
        }
        // Why: a headless host fails markdown.readTab (renderer_unavailable); fall back to the on-disk file for read-only render.
        const fallback = await client.sendRequest('files.read', {
          worktree: `id:${worktreeId}`,
          relativePath: tab.relativePath
        })
        if (!fallback.ok) {
          throw new Error('Unable to read markdown')
        }
        const fileResult = (fallback as RpcSuccess).result as {
          content: string
          truncated: boolean
          byteLength: number
        }
        setMarkdownDocs((prev) =>
          new Map(prev).set(
            tab.id,
            buildMarkdownDiskFallbackDoc({
              content: fileResult.content,
              truncated: fileResult.truncated,
              tabIsDirty: tab.isDirty
            })
          )
        )
      } catch {
        setMarkdownDocs((prev) =>

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Verify the file still exists at tab.relativePath in the worktree — it may have been deleted or moved.
  2. Check the underlying files.read RPC error (currently discarded — the error is a generic string) by inspecting the fallback response.
  3. If on a remote/headless host, confirm the worktree is still mounted and accessible.
  4. Refresh the session tabs to get current file paths, then retry.

Example fix

// before: generic error hides the RPC failure detail
if (!fallback.ok) {
  throw new Error('Unable to read markdown')
}

// after: surface the actual failure reason for debugging
if (!fallback.ok) {
  throw new Error(
    `Unable to read markdown: ${(fallback as RpcFailure).error.message}`
  )
}
Defensive patterns

Strategy: fallback

Validate before calling

async function canReadFile(client, worktreeId, relativePath) {
  const probe = await client.sendRequest('files.read', {
    worktree: `id:${worktreeId}`, relativePath
  })
  return probe.ok
}

Type guard

function isFilesReadResult(value) {
  return value !== null && typeof value === 'object' &&
    typeof value.content === 'string' &&
    typeof value.truncated === 'boolean'
}

Try / catch

try {
  const fallback = await client.sendRequest('files.read', { worktree, relativePath })
  if (!fallback.ok) {
    throw new Error(
      `Unable to read markdown: ${(fallback as RpcFailure).error.message}`
    )
  }
} catch {
  setMarkdownDocs((prev) => new Map(prev).set(tab.id, { status: 'error', message: "Couldn't load markdown" }))
}

Prevention

When it happens

Trigger: markdown.readTab fails with renderer_unavailable (shouldReadMarkdownFromDiskAfterReadTabFailure returns true), then client.sendRequest('files.read', {...}) returns with ok: false. The file is unreadable at the RPC level — file deleted between tab open and read, permission denied, or the worktree path is invalid.

Common situations: A headless/SSH desktop host where the renderer is unavailable AND the file was deleted or moved; a race condition where the tab's relativePath no longer exists; the worktree ID being stale after a workspace change; a remote host with filesystem access issues.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/5270ad3e097a538e. Report an issue: GitHub.