makeplane/plane · error · Error
Invalid valueStop: ${anchorStop}. Must be one of ${SHADE_STO
Error message
Invalid valueStop: ${anchorStop}. Must be one of ${SHADE_STOPS.join(", ")} What it means
When options.valueStop is provided as a number (not 'auto'), generateColorPalette checks it against SHADE_STOPS via isValidShadeStop. The valueStop is the shade anchor (the stop whose lightness equals the input color); it must be one of the supported stops. 'auto' skips this check and computes a dynamic stop; an out-of-range number is rejected.
Source
Thrown at packages/utils/src/theme/palette-generator.ts:142
const inputOKLCH = hexToOKLCH(normalizedHex);
const { l: inputL, c: inputC, h: inputH } = inputOKLCH;
const DEFAULT_LIGHTNESS_MIN = mode === "light" ? DEFAULT_LIGHT_MODE_LIGHTNESS_MIN : DEFAULT_DARK_MODE_LIGHTNESS_MIN;
const DEFAULT_LIGHTNESS_MAX = mode === "light" ? DEFAULT_LIGHT_MODE_LIGHTNESS_MAX : DEFAULT_DARK_MODE_LIGHTNESS_MAX;
// Extract options with defaults
const {
lightnessMin = DEFAULT_LIGHTNESS_MIN / 100, // Convert to 0-1 scale
lightnessMax = DEFAULT_LIGHTNESS_MAX / 100, // Convert to 0-1 scale
valueStop = options.valueStop ?? DEFAULT_VALUE_STOP,
} = options;
// Calculate or use provided valueStop
const anchorStop = valueStop === "auto" ? calculateDynamicValueStop(inputOKLCH) : valueStop;
// Validate valueStop if provided manually
if (typeof anchorStop === "number" && !isValidShadeStop(anchorStop)) {
throw new Error(`Invalid valueStop: ${anchorStop}. Must be one of ${SHADE_STOPS.join(", ")}`);
}
// Create lightness distribution with three anchor points
const distributionAnchors = [
{ stop: SHADE_STOPS[0], lightness: lightnessMax }, // Lightest
{ stop: anchorStop, lightness: inputL }, // Input color
{ stop: SHADE_STOPS[SHADE_STOPS.length - 1], lightness: lightnessMin }, // Darkest
];
// Generate palette by interpolating lightness for each stop
const palette: Partial<ColorPalette> = {};
SHADE_STOPS.forEach((stop) => {
let targetLightness: number;
// Check if this is an anchor point
const anchor = distributionAnchors.find((a) => a.stop === stop);
if (anchor) {View on GitHub (pinned to 1c8a60f858)
Solutions
- Use { valueStop: 'auto' } unless you have a specific reason to pin.
- If pinning, pick from SHADE_STOPS (import and reference the array rather than hard-coding).
- Validate the configured valueStop on app boot and reset to a valid default.
Example fix
// before
generateColorPalette(color, 'light', { valueStop: 99 });
// after
import { SHADE_STOPS } from './theme/palette-generator';
const stop = SHADE_STOPS.includes(config.valueStop) ? config.valueStop : 'auto';
generateColorPalette(color, 'light', { valueStop: stop }); Defensive patterns
Strategy: validation
Validate before calling
import { SHADE_STOPS } from './theme/palette-generator';
const stop = options.valueStop === 'auto' || (typeof options.valueStop === 'number' && SHADE_STOPS.includes(options.valueStop)) ? options.valueStop : 'auto'; Type guard
function isValidStop(s: unknown): boolean { return s === 'auto' || (typeof s === 'number' && SHADE_STOPS.includes(s as number)); } Try / catch
try { generateColorPalette(c, 'light', { valueStop }); } catch (e) { if (/Invalid valueStop/.test((e as Error).message)) { generateColorPalette(c, 'light', { valueStop: 'auto' }); } else throw e; } Prevention
- Prefer valueStop: 'auto'
- Reference SHADE_STOPS instead of hard-coding
- Validate theme config on app boot
When it happens
Trigger: generateColorPalette(color, 'light', { valueStop: 99 }); generateColorPalette(color, 'light', { valueStop: 0 } if 0 is not in SHADE_STOPS); any numeric valueStop outside SHADE_STOPS.
Common situations: Hard-coding a valueStop from an older version when SHADE_STOPS changed; config file with a typo; copy-pasted options from another theme tool with a different scale.
Related errors
- Invalid hex color: ${baseColor}
- Missing required fields.
- Invalid file type. Please select an image.
- Invalid expression: empty or null data
- AND group must contain at least one condition
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/6a946bc2ed574eca.
Report an issue: GitHub.