pbakaus/impeccable · error · Error
surface brief requires a concrete project-relative primary…
Error message
surface brief requires a concrete project-relative primary target or URL
What it means
Thrown by writeSurfaceBrief when normalizeSurfaceTarget returns a falsy value for primaryTarget. A surface brief must name one concrete, project-relative file path or a URL that the brief documents; normalizeSurfaceTarget rejects anything it cannot anchor — values that are not strings, bare names that resolve to no existing project file, or paths that escape the project root. Related targets that fail normalization are silently filtered instead, but the primary target is mandatory.
Solutions
- Pass an existing project-relative path such as 'src/pages/index.astro' or a full URL.
- Create the target file first if it does not exist yet, then write the brief.
- Check the spelling of the primaryTarget option name in the call.
- Use resolveSurfaceTarget/normalizeSurfaceTarget on the value first to see why it fails to anchor.
Example fix
// before
writeSurfaceBrief({ projectRoot, primaryTarget: 'homepage' }); // no such file -> throws
// after
writeSurfaceBrief({ projectRoot, primaryTarget: 'src/pages/index.astro' });
writeSurfaceBrief({ projectRoot, primaryTarget: 'https://example.com/pricing' }); Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path';
function isAnchoredTarget(target, projectRoot) {
if (typeof target !== 'string' || !target.trim()) return false;
if (/^https?:\/\//.test(target)) return true;
const abs = path.resolve(projectRoot, target);
return abs.startsWith(path.resolve(projectRoot) + path.sep) && fs.existsSync(abs);
}
if (!isAnchoredTarget(primaryTarget, projectRoot)) throw new Error('primaryTarget must be an existing project-relative path or a URL'); Type guard
function isValidPrimaryTarget(t, projectRoot) {
return typeof t === 'string' && t.trim().length > 0 &&
(/^https?:\/\//.test(t) ||
(path.resolve(projectRoot, t).startsWith(path.resolve(projectRoot) + path.sep) &&
require('node:fs').existsSync(path.resolve(projectRoot, t))));
} Prevention
- Always pass a path that exists on disk under the project root, or an absolute http(s) URL.
- Create the target file before writing its brief.
- Spell the option exactly primaryTarget; relatedTargets are optional and normalized loosely, the primary is not.
When it happens
Trigger: Calling writeSurfaceBrief({ primaryTarget: undefined }) or with the key misspelled; passing a bare page name like 'home' that matches no project file; passing '../outside/index.html' which resolves outside projectRoot; passing an empty string.
Common situations: Agents writing briefs from a plan document where the target was described but never resolved to a real path; callers assuming any label works; typos in the prop name (target vs primaryTarget); target file not yet created.
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/1fd0b1d9b79cc909.
Report an issue: GitHub.
Appendix: source
Thrown at skill/scripts/lib/surface-briefs.mjs:132
const exactPath = surfaceBriefPathForTarget(normalized, { projectRoot });
const exact = briefs.find((brief) => brief.path === exactPath && (!brief.targets.length || brief.targets.includes(normalized)));
if (exact) return { brief: exact, candidates: briefs, reason: 'slug' };
const mapped = briefs.filter((brief) => brief.targets.includes(normalized));
return {
brief: mapped.length === 1 ? mapped[0] : null,
candidates: mapped.length > 1 ? mapped : briefs,
reason: mapped.length === 1 ? 'mapping' : mapped.length > 1 ? 'ambiguous-target' : 'not-found',
};
}
export function writeSurfaceBrief({
projectRoot = process.cwd(),
primaryTarget,
relatedTargets = [],
body,
}) {
const normalizedPrimary = normalizeSurfaceTarget(primaryTarget, { projectRoot });
if (!normalizedPrimary) throw new Error('surface brief requires a concrete project-relative primary target or URL');
const normalizedRelated = [...new Set(relatedTargets
.map((target) => normalizeSurfaceTarget(target, { projectRoot }))
.filter((target) => target && target !== normalizedPrimary))];
const slug = slugFromTarget(normalizedPrimary, { cwd: projectRoot });
const filePath = surfaceBriefPathForTarget(normalizedPrimary, { projectRoot });
fs.mkdirSync(path.dirname(filePath), { recursive: true });
const frontmatter = [
'---',
`version: ${SURFACE_BRIEF_VERSION}`,
`slug: ${JSON.stringify(slug)}`,
`primary_target: ${JSON.stringify(normalizedPrimary)}`,
`related_targets: ${JSON.stringify(normalizedRelated)}`,
'---',
].join('\n');
fs.writeFileSync(filePath, `${frontmatter}\n\n${String(body || '').trim()}\n`, 'utf-8');
return filePath;
}
View on GitHub (pinned to f88b2837a7)