block/buzz · error · Error
Choose a project.
Error message
Choose a project.
What it means
The ProjectsCategoryCreateDialogs channel-creation flow throws this error to enforce an internal invariant: the dialog's create-channel callback should only be reachable when a project (`channelProject`) has already been selected for the channel. The surrounding UI text says 'Choose a project for this channel', and `onCreate` refuses to run the mutation when `channelProject` is null. Hitting this means the code path invoked without the project being resolved — the guard is a defensive assertion, not an expected user-facing error.
Source
Thrown at desktop/src/features/projects/ui/ProjectsCategoryCreateDialogs.tsx:57
channel.isMember &&
!channel.archivedAt &&
channel.channelType !== "dm",
),
[channelsQuery.data],
);
return (
<>
<CreateChannelDialog
channelKind={channelOpen ? "stream" : null}
description={
channelProject
? `Add another stream to ${channelProject.name}.`
: "Choose a project for this channel."
}
isCreating={createChannelMutation.isPending}
onCreate={async (input) => {
if (!channelProject) throw new Error("Choose a project.");
const result = await createChannelMutation.mutateAsync({
...input,
ownerControlAgentPubkey: ownerControlAgentPubkeyFor(channelProject),
project: channelProject,
});
toast.success(`Channel "#${result.channel.name}" created.`);
await goChannel(result.channel.id);
}}
onOpenChange={onChannelOpenChange}
testId="create-project-channel-dialog"
title="Create a project channel"
>
<label className="block space-y-1.5 text-sm font-medium">
<span>Project</span>
<select
className="h-10 w-full rounded-lg border border-input bg-background px-3 text-sm font-normal outline-hidden focus:ring-1 focus:ring-ring"
data-testid="create-project-channel-project"
disabled={createChannelMutation.isPending}View on GitHub (pinned to eed74bde2f)
Solutions
- Select a project in the dialog's project picker before submitting the create-channel form.
- Disable the submit button when `!channelProject` so the handler can never run without a project.
- If `channelProject` should be derived automatically, verify the query/hook that sets it actually resolved and did not fail.
- In tests, seed the project selection state before invoking onCreate.
Example fix
// before
onCreate={async (input) => {
if (!channelProject) throw new Error("Choose a project.");
...
}}
// after — prevent submission instead of throwing
<button
disabled={!channelProject || createChannelMutation.isPending}
onClick={() => formRef.current?.requestSubmit()}
/>
onCreate={async (input) => {
if (!channelProject) return; // unreachable when button is disabled
...
}} Defensive patterns
Strategy: validation
Validate before calling
if (!channelProject) {
toast.error("Select a project before creating the channel.");
return;
}
await createChannelMutation.mutateAsync({ ...input, project: channelProject }); Type guard
const hasProject = (p: unknown): p is { id: string; name: string } =>
typeof p === "object" && p !== null && "id" in p && "name" in p; Try / catch
try {
await createChannelMutation.mutateAsync({ ...input, project: channelProject! });
} catch (e) {
if (e instanceof Error && e.message === "Choose a project.") {
toast.error("Select a project first.");
} else throw e;
} Prevention
- Disable the submit/create button while channelProject is null.
- Surface the project picker as a required step in the dialog flow.
- Write a test asserting onCreate is unreachable without a project selection.
When it happens
Trigger: Calling the dialog's `onCreate` handler while `channelProject` is null/undefined: the user (or a test/e2e harness) submits the create-channel form before a project is selected, or the project lookup that sets `channelProject` failed silently while the submit action remained enabled.
Common situations: UI state where the 'create channel' button is clickable before a project picker selection; a race where the project query has not resolved but the form is submitted; automated tests invoking onCreate without first choosing a project; channel project fetch failing (e.g. relay unreachable) leaving channelProject null.
Related errors
- Choose a channel first.
- plugin.json unknown key "{key}"
- plugin.json defaults: unknown key "{key}"
- plugin.json defaults.triggers: unknown key "{key}"
- skill {label}: name "{name_str}" differs from directory name
AI-assisted analysis of block/buzz@eed74bde2f (2026-08-30).
Data as JSON: /api/errors/6ff12147b6c45f42.
Report an issue: GitHub.