nexu-io/open-design · error · Error
invalid brand id: ${id}
Error message
invalid brand id: ${id} What it means
Thrown by the private brandRoot helper in system.ts when resolveBrandFile(brandsRoot, id, []) returns null. brandRoot backs brandSystemDir and readFontManifest inside rebuildSystem, so any caller of rebuildSystem with an invalid id ultimately hits this. Same regex + traversal guard as the store.
Source
Thrown at apps/daemon/src/brands/system.ts:40
type SeedToken,
type ThemeAlgorithm,
} from './engine/index.js';
import type { AssetKind, Brand } from './schema.js';
export const BRAND_ARTIFACT_KINDS: AssetKind[] = [
'landing',
'deck',
'poster',
'email',
'newsletter',
'form',
];
const THEME_ALGORITHMS: ThemeAlgorithm[] = ['default', 'dark', 'compact'];
function brandRoot(brandsRoot: string, id: string): string {
const dir = resolveBrandFile(brandsRoot, id, []);
if (!dir) throw new Error(`invalid brand id: ${id}`);
return dir;
}
export function brandSystemDir(brandsRoot: string, id: string): string {
return path.join(brandRoot(brandsRoot, id), 'system');
}
function reassembleWithSeed(
base: BrandSystem,
brand: Brand,
seed: SeedToken,
fontFiles: FontFile[],
): BrandSystem {
const themes: Record<ThemeAlgorithm, DesignTokens> = {
default: deriveTokens(seed, 'default'),
dark: deriveTokens(seed, 'dark'),
compact: deriveTokens(seed, 'compact'),
};View on GitHub (pinned to 5be4028344)
Solutions
- Validate the id with isValidBrandId and confirm readBrand(brandsRoot, id) !== null before rebuildSystem.
- Source rebuild ids from listBrandIds output only.
- In the rebuild route, return 404 for a missing brand rather than letting brandRoot throw.
- Order checks in rebuildSystem consumers: exists -> rebuild, so brandRoot is never reached for missing ids.
Example fix
// before
await rebuildSystem(brandsRoot, id);
// after
import { isValidBrandId, readBrand } from './store.js';
if (!isValidBrandId(id) || !readBrand(brandsRoot, id)) {
throw new HttpError(404, `brand not found: ${id}`);
}
await rebuildSystem(brandsRoot, id); Defensive patterns
Strategy: validation
Validate before calling
import { isValidBrandId, readBrand } from './store.js';
if (!isValidBrandId(id) || !readBrand(brandsRoot, id)) {
throw new Error(`brand not found: ${id}`);
} Type guard
import { isValidBrandId } from './store.js';
const isBrandId = (id: unknown): id is string =>
typeof id === 'string' && isValidBrandId(id); Prevention
- Validate id and existence before rebuildSystem.
- Source rebuild ids from listBrandIds output.
- Order checks: exists -> rebuild, so brandRoot is never reached for missing ids.
When it happens
Trigger: rebuildSystem(brandsRoot, id) invoked with an id that fails isValidBrandId. Because rebuildSystem first calls readBrand (which returns null for the same invalid id), error [51] usually fires first — but if readBrand is bypassed or the id is valid-yet-missing, brandRoot throws here instead.
Common situations: Rebuild route that accepts the id from the request path; tests that call rebuildSystem directly with a fabricated id; a stale id cached after the brand was deleted; a refactor that called brandSystemDir before readBrand.
Related errors
- invalid brand id: ${id}
- brand.json not found for brand "${id}"
- invalid brand id: ${brandId}
- proposal patch.after markdown is required
- invalid design system id: ${designSystemId}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/9b341849d3674a46.
Report an issue: GitHub.