pbakaus/impeccable · error · Error
surface brief requires a concrete project-relative primary t
Error message
surface brief requires a concrete project-relative primary target or URL
What it means
Thrown by writeSurfaceBrief() in skill/scripts/lib/surface-briefs.mjs when normalizeSurfaceTarget() returns null for the primaryTarget. normalizeSurfaceTarget accepts an http(s) URL, a `route:/path`, a lone `/`, or a project-relative path that does not escape the project root (no `..`, stays inside projectRoot). Anything else — absolute path outside the project, a `..` traversal, an unparseable URL, or a non-string — yields null and this error.
Source
Thrown at skill/scripts/lib/surface-briefs.mjs:134
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 d14711ae3d)
Solutions
- Pass a project-relative path (e.g. `src/pages/home.astro`), an `http(s)://` URL, or a `route:/path` for an in-app route.
- If you meant a route, prefix it with `route:` or pass it starting with `/` that does not resolve to an existing outside file.
- Confirm projectRoot is the repo root so the relative-path normalization does not misclassify the target.
Example fix
// before
writeSurfaceBrief({ primaryTarget: '/Users/me/site/src/pages/home.astro' });
// after
writeSurfaceBrief({ projectRoot, primaryTarget: 'src/pages/home.astro' }); Defensive patterns
Strategy: validation
Validate before calling
import { normalizeSurfaceTarget } from './surface-briefs.mjs';
const normalized = normalizeSurfaceTarget(primaryTarget, { projectRoot });
if (!normalized) {
throw new Error('primaryTarget must be a project-relative path, http(s) URL, or route:/path');
} Type guard
function isUsableSurfaceTarget(target, projectRoot) {
return normalizeSurfaceTarget(target, { projectRoot }) !== null;
} Prevention
- Pass project-relative paths, not absolute filesystem paths.
- Prefix in-app routes with route: or a leading /.
- Always pass projectRoot explicitly.
When it happens
Trigger: Calling writeSurfaceBrief({ primaryTarget }) with a value like `/etc/passwd` (absolute, outside project, existing file so not treated as a route), `../outside`, a malformed URL (`http://[broken`), an empty string, or a non-string. Also a bare string that resolves outside projectRoot.
Common situations: Passing an absolute filesystem path instead of a project-relative one; passing a URL with a typo; forgetting to set projectRoot so the relative-path check uses the wrong base; feeding user input unchecked.
Related errors
- surface brief path requires a concrete target
- usage: surface-brief.mjs write <primary-target> <body-file>
- concept-seed: every challenger tier needs at least one appro
- invalid catalog: ${validation.errors.join('; ')}
- concept-seed: --scope must be direction or surface
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/1fd0b1d9b79cc909.
Report an issue: GitHub.