makeplane/plane · error · Error

Missing required fields.

Error message

Missing required fields.

What it means

First of eight identical guards in the ProjectPage constructor (apps/web/core/store/pages/project-page.ts). The `update` handler throws 'Missing required fields.' when any of workspaceSlug (from store.router), projectId (page.project_ids[0]), or page.id is absent. These three are required path parameters for every projectPageService call.

Source

Thrown at apps/web/core/store/pages/project-page.ts:31

import type { RootStore } from "@/store/root.store";
// services
import { ProjectPageService } from "@/services/page";
const projectPageService = new ProjectPageService();
// store
import { BasePage } from "./base-page";
import type { TPageInstance } from "./base-page";

export type TProjectPage = TPageInstance;

export class ProjectPage extends BasePage implements TProjectPage {
  constructor(store: RootStore, page: TPage) {
    // required fields for API calls
    const { workspaceSlug } = store.router;
    const projectId = page.project_ids?.[0];
    // initialize base instance
    super(store, page, {
      update: async (payload) => {
        if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
        return await projectPageService.update(workspaceSlug, projectId, page.id, payload);
      },
      updateDescription: async (document) => {
        if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
        await projectPageService.updateDescription(workspaceSlug, projectId, page.id, document);
      },
      updateAccess: async (payload) => {
        if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
        await projectPageService.updateAccess(workspaceSlug, projectId, page.id, payload);
      },
      lock: async () => {
        if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
        await projectPageService.lock(workspaceSlug, projectId, page.id);
      },
      unlock: async () => {
        if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
        await projectPageService.unlock(workspaceSlug, projectId, page.id);
      },

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Ensure the page is rendered within a route where workspaceSlug and projectId are resolved before enabling edit actions.
  2. Validate page.project_ids?.[0] and page.id are non-empty when constructing ProjectPage; skip instantiation otherwise.
  3. Gate mutation UI on a computed `canEdit` that checks all three fields.
  4. If the fields can legitimately be absent, lazy-resolve them (await router/scrollToPage) before invoking update.

Example fix

// before
update: async (payload) => {
  if (!workspaceSlug || !projectId || !page.id) throw new Error("Missing required fields.");
  return await projectPageService.update(workspaceSlug, projectId, page.id, payload);
}
// after: early no-op with a warning instead of a hard throw
update: async (payload) => {
  if (!workspaceSlug || !projectId || !page.id) {
    console.warn('ProjectPage.update skipped: missing identifiers');
    return;
  }
  return await projectPageService.update(workspaceSlug, projectId, page.id, payload);
}
Defensive patterns

Strategy: validation

Validate before calling

const { workspaceSlug } = store.router;
const projectId = page.project_ids?.[0];
if (!workspaceSlug || !projectId || !page.id) { console.warn('update skipped'); return; }

Type guard

const hasPageIdentifiers = (s: {workspaceSlug?: string}, p: {project_ids?: string[]; id?: string}) =>
  Boolean(s.workspaceSlug && p.project_ids?.[0] && p.id);

Try / catch

try { await page.update(payload); }
catch (e) { if (/Missing required fields/.test(e.message)) showPageNotReady(); else throw e; }

Prevention

When it happens

Trigger: Invoking page.update() before router params are populated; constructing a ProjectPage from a TPage that has no project_ids or no id; calling update during route transitions where router.workspaceSlug is briefly undefined.

Common situations: Optimistic page mutation fired on mount before route resolution; page record loaded from a partial/socket payload missing project_ids; navigating away mid-edit leaves a stale page instance whose router context is gone.

Related errors


AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12). Data as JSON: /api/errors/ee00266145dc5eb2. Report an issue: GitHub.