nexu-io/open-design · error
brand not found: ${opts.id}
Error message
brand not found: ${opts.id} What it means
Thrown by continueBrandExtraction when readBrandDetail(brandsRoot, opts.id) returns null, i.e. no brand directory/meta exists for that id. The route handler maps /not found/i to HTTP 404.
Source
Thrown at apps/daemon/src/brands/index.ts:689
if (isClosedDatabaseError(err)) return null;
console.warn(`[brand] failed to reconcile programmatic extraction transcript for ${id}`, err);
return null;
})
.finally(() => {
extractionSettled = true;
clearTimeout(stallTimer);
clearTimeout(hardCapTimer);
});
input.onBackgroundExtraction?.(settled);
return settled;
}
export async function continueBrandExtraction(
opts: ContinueBrandExtractionOptions,
): Promise<StartBrandExtractionResult> {
const detail = readBrandDetail(opts.brandsRoot, opts.id);
if (!detail) throw new Error(`brand not found: ${opts.id}`);
const { meta } = detail;
const sourceUrl = meta.sourceUrl;
const projectId = meta.projectId ?? brandProjectId(opts.id);
const project = getProject(opts.db, projectId);
if (!project) throw new Error(`brand backing project not found: ${projectId}`);
const randomId = opts.randomId ?? randomUUID;
const locale = normalizeBrandKitLocale(opts.locale ?? meta.locale);
const hasWebsiteSource = /^https?:\/\//i.test(sourceUrl);
const designMd = readDesignMdInput(opts.brandsRoot, opts.id);
const hasDesignMdSource = Boolean(designMd) || sourceUrl.startsWith('designmd://');
const host = hostnameOf(sourceUrl);
const now = Date.now();
const extractionAttemptId = newBrandExtractionAttemptId();
const conversationId = resolveBrandRetryConversationId({
db: opts.db,
projectId,
preferredConversationId: meta.conversationId ?? null,View on GitHub (pinned to 5be4028344)
Solutions
- List brands via the brand list endpoint to confirm the id exists.
- If the brand was deleted, start a new extraction with startBrandExtraction instead of continue.
- Verify the daemon is using the expected brandsRoot (OD_DATA_DIR / RUNTIME_DATA_DIR).
Defensive patterns
Strategy: validation
Validate before calling
const detail = readBrandDetail(brandsRoot, opts.id);
if (!detail) {
throw new NotFoundError(`No brand with id '${opts.id}'. Create one with startBrandExtraction first.`);
} Type guard
function isExistingBrand(detail: unknown): detail is BrandDetailResponse {
return detail !== null && detail !== undefined;
} Try / catch
try {
await continueBrandExtraction(opts);
} catch (err) {
if (err instanceof Error && /^brand not found:/.test(err.message)) {
return notFound('That brand no longer exists. Start a new extraction.');
}
throw err;
} Prevention
- List brands before offering a Continue action in the UI.
- Invalidate client-side references when a brand is deleted.
- Confirm the daemon's brandsRoot is the same one where the brand was created.
When it happens
Trigger: Continuing an extraction for a brand id that was deleted, never created, or was mistyped; the brandsRoot was changed/relocated between requests.
Common situations: Restarting after clearing the data directory; a stale client link from a previous session; copy-paste error in the id.
Related errors
- brand backing project not found: ${projectId}
- brand not found: ${id}
- brand.json not found in the extraction project — the agent h
- automation proposal not found
- Could not fetch ${url} — the site may block server-side requ
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/4381ba783a674276.
Report an issue: GitHub.