bytedance/deer-flow · warning · Error

No context selected

Error message

No context selected

What it means

ensureSidecarThread lazily creates the sidecar (sub-thread) conversation: it returns the existing sidecarThreadId, or restores a persisted one, and only then creates a new thread with the passed references as context. If references is empty at that point, there is nothing to seed the sidecar with, so it throws the localized 'no context selected' error instead of creating an empty sidecar thread.

Source

Thrown at frontend/src/components/workspace/sidecar/sidecar-panel.tsx:326

        ...sidecar.context,
        mode: nextMode,
        reasoning_effort: reasoningEffortForMode(nextMode),
      });
    },
    [sidecar, supportThinking],
  );

  const ensureSidecarThread = useCallback(
    async (references: SidecarReference[]) => {
      if (sidecar.sidecarThreadId) {
        return sidecar.sidecarThreadId;
      }
      const restoredThreadId = await sidecar.restoreSidecarThread();
      if (restoredThreadId) {
        return restoredThreadId;
      }
      if (references.length === 0) {
        throw new Error(t.sidecar.noContext);
      }
      setCreatingThread(true);
      try {
        const created = await createSidecarThread({
          parentThreadId: sidecar.parentThreadId,
          context: references.map((reference) => reference.context),
        });
        sidecar.setSidecarThreadId(created.thread_id);
        return created.thread_id;
      } finally {
        setCreatingThread(false);
      }
    },
    [sidecar, t.sidecar.noContext],
  );

  const submitToSidecarThread = useCallback(
    async (

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Select a message quote, artifact, or file reference first, then trigger the sidecar action.
  2. If the reference should exist, check that the component passes a non-empty SidecarReference[] array into the action handler.
  3. If a previous sidecar thread should have been restored, verify the persisted parent thread id matches and restoreSidecarThread did not silently fail (check its console/network log).
  4. Guard the action button with `disabled={references.length === 0}` when no sidecar thread exists yet.

Example fix

// before
<button onClick={() => sendToSidecar()}>Ask sidecar</button>

// after
<button
  disabled={!sidecar.sidecarThreadId && references.length === 0}
  onClick={() => sendToSidecar()}
>
  Ask sidecar
</button>
Defensive patterns

Strategy: validation

Validate before calling

if (!sidecar.sidecarThreadId && references.length === 0) {
  toast.warn(t.sidecar.noContext);
  return;
}
const threadId = await ensureSidecarThread(references);

Type guard

function hasSidecarContext(
  sidecar: { sidecarThreadId?: string | null },
  references: SidecarReference[],
): boolean {
  return Boolean(sidecar.sidecarThreadId) || references.length > 0;
}

Try / catch

try {
  await ensureSidecarThread(references);
} catch (e) {
  if (e instanceof Error && e.message === t.sidecar.noContext) toast.warn(e.message);
  else throw e;
}

Prevention

When it happens

Trigger: The user triggers a sidecar action (e.g. 'ask about this' / quote into sidecar) with no selection, artifact, or message reference attached — references === [] — while sidecar.sidecarThreadId is unset and restoreSidecarThread() returned falsy (no prior sidecar thread persisted for this parent).

Common situations: UI race where the reference list has not loaded yet but the action button fired; a stale panel re-mounted after the sidecar thread was cleared; calling the sidecar send path programmatically without providing context references.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/66ed93730cba3d61. Report an issue: GitHub.