{"record":{"id":"8c3f99603032cd14","repo":"eyaltoledano/claude-task-master","slug":"no-brief-selected-8c3f99","errorCode":"NO_BRIEF_SELECTED","errorMessage":"No brief context found for watching. Please connect to a brief first.","messagePattern":"No brief context found for watching\\. Please connect to a brief first\\.","errorType":"exception","errorClass":"TaskMasterError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/storage/adapters/api-storage.ts","lineNumber":965,"sourceCode":"\t/**\n\t * Watch for changes to tasks via Supabase Realtime\n\t * Subscribes to postgres_changes for the tasks table filtered by brief_id\n\t *\n\t * Optional debouncing is supported for collaborative scenarios where multiple\n\t * rapid changes (e.g., bulk operations, multiple users) could cause UI flicker.\n\t * Default: 300ms (higher than FileStorage's 100ms since Realtime events are cleaner)\n\t */\n\tasync watch(\n\t\tcallback: (event: WatchEvent) => void,\n\t\toptions?: WatchOptions\n\t): Promise<WatchSubscription> {\n\t\tawait this.ensureInitialized();\n\n\t\tconst authManager = AuthManager.getInstance();\n\t\tconst context = authManager.getContext();\n\n\t\tif (!context?.briefId) {\n\t\t\tthrow new TaskMasterError(\n\t\t\t\t'No brief context found for watching. Please connect to a brief first.',\n\t\t\t\tERROR_CODES.NO_BRIEF_SELECTED,\n\t\t\t\t{ operation: 'watch' }\n\t\t\t);\n\t\t}\n\n\t\tconst supabase = authManager.supabaseClient.getClient();\n\t\tconst channelName = `tasks-watch-${context.briefId}-${Date.now()}`;\n\t\tconst debounceMs = options?.debounceMs ?? 300;\n\n\t\tlet debounceTimer: NodeJS.Timeout | undefined;\n\t\tlet closed = false;\n\n\t\tconst debouncedCallback = () => {\n\t\t\tif (closed) return;\n\t\t\tif (debounceTimer) {\n\t\t\t\tclearTimeout(debounceTimer);\n\t\t\t}","sourceCodeStart":947,"sourceCodeEnd":983,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/storage/adapters/api-storage.ts#L947-L983","documentation":"TaskMasterError with code NO_BRIEF_SELECTED thrown by ApiStorage.watch when AuthManager's context has no briefId. Real-time watching is scoped to a brief, so without a connected brief the adapter refuses to start a watcher instead of watching nothing.","triggerScenarios":"Calling storage.watch() (or watch on a collection) before authenticating, after authentication but without connecting/selecting a brief, or after the stored auth context was cleared/expired so context?.briefId is undefined.","commonSituations":"CLI/automation started fresh without a prior 'connect to brief' step, CI job missing the brief-selection env/config, a logged-out or expired session dropping the brief context, or running watch in a code path that never sets up AuthManager context.","solutions":["Connect to a brief first (the auth/connect flow that populates AuthManager context with briefId), then call watch.","Check AuthManager.getInstance().getContext()?.briefId before calling watch and short-circuit with a friendly prompt.","Re-authenticate if the session expired and the brief context was lost.","In CI/automation, ensure brief selection is configured via env/config before any watch call."],"exampleFix":"// before\nconst watcher = await storage.watch(cb); // throws NO_BRIEF_SELECTED\n// after\nconst ctx = AuthManager.getInstance().getContext();\nif (!ctx?.briefId) {\n  await connectToBrief(briefId); // sets auth context\n}\nconst watcher = await storage.watch(cb);","handlingStrategy":"validation","validationCode":"import { AuthManager } from '@tm/core';\nconst ctx = AuthManager.getInstance().getContext();\nif (!ctx?.briefId) {\n  throw new Error('No brief connected. Run the connect flow before watch().');\n}","typeGuard":"function hasBriefContext(ctx: { briefId?: string } | null | undefined): ctx is { briefId: string } {\n  return typeof ctx?.briefId === 'string' && ctx.briefId.length > 0;\n}","tryCatchPattern":"try {\n  const watcher = await storage.watch(onChange);\n} catch (e) {\n  if ((e as TaskMasterError).code === 'NO_BRIEF_SELECTED') {\n    await promptBriefSelection(); // interactive or env-based connect\n    return;\n  }\n  throw e;\n}","preventionTips":["Always run the brief connect/auth flow before enabling watchers.","In CI, supply brief selection via env/config and assert it at startup.","Re-check the brief context after re-authentication, since expiry can drop it.","Check error code NO_BRIEF_SELECTED specifically to distinguish config issues from network failures."],"tags":["watch","auth","brief","configuration"],"backgroundTag":"missing-brief-context","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}