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
- Ensure the page is rendered within a route where workspaceSlug and projectId are resolved before enabling edit actions.
- Validate page.project_ids?.[0] and page.id are non-empty when constructing ProjectPage; skip instantiation otherwise.
- Gate mutation UI on a computed `canEdit` that checks all three fields.
- 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
- Only mount page edit UI inside a resolved route context.
- Compute a `canEdit` flag from the three identifiers and use it to disable actions.
- Refetch the page if project_ids is empty before exposing actions.
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
- Member not found
- Member not found
- Workspace not found
- Issue not found
- Failed to fetch image: ${response.statusText}
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/ee00266145dc5eb2.
Report an issue: GitHub.