stablyai/orca · error · LinearWriteFailure

failed

failed

Error message

Not connected to Linear

What it means

Thrown by writeIssueRelation when getClients(params.workspaceId)[0] is undefined, i.e. no Linear client matches the requested workspace. The library requires a connected (token-loaded) workspace before any relation mutation. It fails fast with kind='failed' rather than silently no-oping.

Source

Thrown at src/main/linear/issue-relation-write.ts:33

} from './issue-context-raw'
import { createLinearIssueRelation, deleteLinearIssueRelation } from './issue-relation-mutation'
import { LinearWriteFailure } from './issues'

const RELATION_WRITE_READ_CAP = 250

type RelationDirection = 'outbound' | 'inbound'

export async function writeIssueRelation(params: {
  issue: LinearIssueRelationWriteResult['issue']
  relatedIssue: LinearIssueRelationWriteResult['relatedIssue']
  relationship: LinearIssueRelationship
  operation: 'add' | 'remove'
  workspaceId: string
  signal?: AbortSignal
}): Promise<LinearIssueRelationWriteResult> {
  const entry = getClients(params.workspaceId)[0]
  if (!entry) {
    throw new LinearWriteFailure('failed', 'Not connected to Linear')
  }
  await acquire()
  try {
    const client = params.signal
      ? new (loadLinearSdk().LinearClient)({ apiKey: entry.apiKey, signal: params.signal })
      : entry.client
    const existing = await findExistingRelation(client, params)
    if (params.operation === 'add' && existing) {
      return result(params, existing, true)
    }
    if (params.operation === 'remove' && !existing) {
      return result(params, absentRelation(params), true)
    }
    if (params.operation === 'remove' && existing) {
      await deleteLinearIssueRelation(client, existing.id)
      return result(params, existing, false)
    }
    const created = await createLinearIssueRelation(client, relationCreateInput(params))

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Verify Linear connection via getLinearStatus(); if not connected, prompt the user through connect/selectWorkspace.
  2. Confirm params.workspaceId matches a connected workspace id in getWorkspaceState().workspaces.
  3. If running from an agent loop, gate relation writes on a connected-workspace precondition before enqueueing.
  4. Check for credential/decrypt errors and trigger a fresh token load.

Example fix

// before
const res = await writeIssueRelation({ issue, relatedIssue, relationship, operation: 'add', workspaceId })
// after
const entry = getClients(workspaceId)[0]
if (!entry) throw new Error(`Linear workspace ${workspaceId} is not connected; cannot write relation`)
const res = await writeIssueRelation({ issue, relatedIssue, relationship, operation: 'add', workspaceId, signal })
Defensive patterns

Strategy: validation

Validate before calling

import { getClients } from './client'
const entry = getClients(params.workspaceId)[0]
if (!entry) throw new Error(`Workspace ${params.workspaceId} not connected; cannot write relation`)

Type guard

import { LinearWriteFailure } from './issues'
function isNotConnectedFailure(e: unknown): boolean {
  return e instanceof LinearWriteFailure && e.kind === 'failed' && e.message === 'Not connected to Linear'
}

Try / catch

try {
  await writeIssueRelation(params)
} catch (e) {
  if (isNotConnectedFailure(e)) { /* prompt connect, do not retry */ }
  else throw e
}

Prevention

When it happens

Trigger: Calling writeIssueRelation with a workspaceId whose token is missing, expired, undecryptable, or that was never registered in workspace state. Also when workspaceId refers to a workspace id that has since been disconnected.

Common situations: User opened the agent flow before completing Linear OAuth, the saved token failed CredentialDecryption, or the workspace was disconnected between when the relation task was queued and when it ran.

Related errors


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