pbakaus/impeccable · 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() when normalizeSurfaceTarget(primaryTarget) returns null. normalizeSurfaceTarget rejects empty/non-string values, malformed URLs (catch falls to null), route: strings that don't start with '/' or contain '..', and filesystem paths whose path.relative() to projectRoot escapes the project (starts with '..'). The brief writer needs one concrete, resolvable primary target so it can slug the file and emit frontmatter.

Source

Thrown at plugin/skills/impeccable/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

  1. Pass a non-empty string that is either an http(s) URL, a route: string starting with '/', an absolute path inside the project, or a relative path that stays within projectRoot.
  2. Pre-validate with the exported normalizeSurfaceTarget() before calling writeSurfaceBrief; if it returns null, surface a user-facing error instead of letting the throw propagate.
  3. For URL inputs, new URL() it yourself first to catch malformed URLs early; trim whitespace and drop fragments/search before passing.
  4. Confirm projectRoot matches the directory the target path is relative to (the default is process.cwd()).

Example fix

// before
writeSurfaceBrief({ primaryTarget: userHref, body });

// after
import { normalizeSurfaceTarget, writeSurfaceBrief } from './lib/surface-briefs.mjs';
const normalized = normalizeSurfaceTarget(userHref, { projectRoot });
if (!normalized) throw new Error(`Invalid primary target: ${JSON.stringify(userHref)}`);
writeSurfaceBrief({ projectRoot, primaryTarget: normalized, body });
Defensive patterns

Strategy: validation

Validate before calling

import { normalizeSurfaceTarget } from './lib/surface-briefs.mjs';
function isValidSurfaceTarget(target, projectRoot) {
  return typeof target === 'string'
    && target.trim().length > 0
    && normalizeSurfaceTarget(target, { projectRoot }) !== null;
}
// call before writeSurfaceBrief
if (!isValidSurfaceTarget(primaryTarget, projectRoot)) {
  throw new Error(`Refusing to write brief: invalid primary target ${JSON.stringify(primaryTarget)}`);
}

Type guard

/** Narrowing guard for surface brief targets. */
function isSurfaceTarget(value, projectRoot) {
  if (typeof value !== 'string' || !value.trim()) return false;
  // Reuse the library's own normalizer as the source of truth.
  try { return normalizeSurfaceTarget(value, { projectRoot }) !== null; }
  catch { return false; }
}

Try / catch

try {
  writeSurfaceBrief({ projectRoot, primaryTarget, relatedTargets, body });
} catch (err) {
  if (/concrete project-relative primary target/.test(err.message)) {
    // prompt the user/agent for a valid target instead of crashing
    return { ok: false, error: 'invalid_primary_target', hint: 'Pass a project-relative path, route:/x, or http(s) URL.' };
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling writeSurfaceBrief({ primaryTarget: '' }), with undefined, with 'route:../x', with 'https:// bad url' (URL constructor throws -> null), or with an absolute path like '/etc/passwd' that resolves outside projectRoot. Also when a relative path equals '.' or resolves to the projectRoot itself (rel === '.' -> null).

Common situations: Programmatically building a brief from user/agent input without pre-validating; passing a DOM href that is a bare fragment ('#foo') or protocol-relative ('//host'); wrong cwd/projectRoot so a legitimately in-project file computes as outside; passing an empty string after trimming. URL inputs with stray whitespace or invalid characters hit the URL constructor catch.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/98343324e3d70b9e. Report an issue: GitHub.