paperclipai/paperclip · error

Select a company to create secrets

Error message

Select a company to create secrets

What it means

createSecret in RoutineDetail is company-scoped: secrets are created under a specific company via secretsApi.create(companyId, input). If no company is selected (selectedCompanyId is null), the mutation throws this error instead of calling the API. It guards against creating a secret with no owning company.

Source

Thrown at ui/src/pages/RoutineDetail.production.tsx:254

  });
  const { data: projects } = useQuery({
    queryKey: queryKeys.projects.list(selectedCompanyId!, { includeArchived: true }),
    queryFn: () => projectsApi.list(selectedCompanyId!, { includeArchived: true }),
    enabled: !!selectedCompanyId,
  });
  const { data: companyMembers } = useQuery({
    queryKey: queryKeys.access.companyUserDirectory(selectedCompanyId!),
    queryFn: () => accessApi.listUserDirectory(selectedCompanyId!),
    enabled: !!selectedCompanyId,
  });
  const { data: availableSecrets = [] } = useQuery({
    queryKey: selectedCompanyId ? queryKeys.secrets.list(selectedCompanyId) : ["secrets", "none"],
    queryFn: () => secretsApi.list(selectedCompanyId!),
    enabled: Boolean(selectedCompanyId),
  });
  const createSecret = useMutation({
    mutationFn: (input: { name: string; value: string }) => {
      if (!selectedCompanyId) throw new Error("Select a company to create secrets");
      return secretsApi.create(selectedCompanyId, input);
    },
    onSuccess: () => {
      if (!selectedCompanyId) return;
      queryClient.invalidateQueries({ queryKey: queryKeys.secrets.list(selectedCompanyId) });
    },
  });

  const routineDefaults = useMemo<RoutineEditDraft | null>(
    () =>
      routine
        ? {
            title: routine.title,
            description: routine.description ?? "",
            projectId: routine.projectId ?? "",
            assigneeAgentId: routine.assigneeAgentId ?? "",
            priority: routine.priority,
            concurrencyPolicy: routine.concurrencyPolicy,

View on GitHub (pinned to 01ad858492)

Solutions

  1. Select a company before submitting the create-secret form.
  2. Disable the form's submit button (or the whole form) when !selectedCompanyId.
  3. Redirect to company selection when this page requires a company and none is chosen.
  4. Ensure the company context provider has finished loading before rendering the secrets panel.

Example fix

// before
mutationFn: (input) => {
  if (!selectedCompanyId) throw new Error("Select a company to create secrets");
  return secretsApi.create(selectedCompanyId, input);
},
// after (form-level guard)
<button type="submit" disabled={!selectedCompanyId || createSecret.isPending}>
  Create secret
</button>
Defensive patterns

Strategy: validation

Validate before calling

if (!selectedCompanyId) {
  toast.info("Select a company to create secrets");
  return;
}

Type guard

const canCreateSecret = (id: string | null | undefined): id is string => typeof id === "string" && id.length > 0;

Try / catch

try {
  await createSecret.mutateAsync({ name, value });
} catch (e) {
  if (e.message === "Select a company to create secrets") toast.info(e.message);
  else toast.error("Could not create secret");
}

Prevention

When it happens

Trigger: Calling createSecret.mutate({ name, value }) while no company is selected in the company context — e.g. submitting the create-secret form before the company selector is populated.

Common situations: Opening the routine detail page before company selection hydrates; the company selector was never set; a deep link that skips company selection; the form remained enabled while company context was loading.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/52c01dd812578ba6. Report an issue: GitHub.