{"record":{"id":"51f8dbffcdbd1159","repo":"pbakaus/impeccable","slug":"surface-brief-path-requires-a-concrete-target-51f8db","errorCode":null,"errorMessage":"surface brief path requires a concrete target","messagePattern":"surface brief path requires a concrete target","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"skill/scripts/surface-brief.mjs","lineNumber":27,"sourceCode":"  surfaceBriefPathForTarget,\n  writeSurfaceBrief,\n} from './lib/surface-briefs.mjs';\n\nfunction summary(brief, projectRoot) {\n  return {\n    slug: brief.slug,\n    path: path.relative(projectRoot, brief.path).split(path.sep).join('/'),\n    primaryTarget: brief.primaryTarget,\n    relatedTargets: brief.relatedTargets,\n  };\n}\n\nfunction main(argv) {\n  const [command, target, bodyFile, ...relatedTargets] = argv;\n  const projectRoot = resolveProjectRoot(process.cwd(), target ? { targetPath: target } : {});\n  if (command === 'path') {\n    const filePath = surfaceBriefPathForTarget(target, { projectRoot });\n    if (!filePath) throw new Error('surface brief path requires a concrete target');\n    process.stdout.write(`${path.relative(process.cwd(), filePath) || filePath}\\n`);\n    return;\n  }\n  if (command === 'list') {\n    process.stdout.write(`${JSON.stringify(listSurfaceBriefs(projectRoot).map((brief) => summary(brief, projectRoot)), null, 2)}\\n`);\n    return;\n  }\n  if (command === 'read') {\n    const result = resolveSurfaceBrief(projectRoot, target || null);\n    if (result.brief) {\n      process.stdout.write(result.brief.text);\n      return;\n    }\n    if (result.candidates.length) process.stderr.write(`${JSON.stringify(result.candidates.map((brief) => summary(brief, projectRoot)), null, 2)}\\n`);\n    process.exit(2);\n  }\n  if (command === 'write') {\n    if (!target || !bodyFile) throw new Error('usage: surface-brief.mjs write <primary-target> <body-file>');","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/surface-brief.mjs#L9-L45","documentation":"Thrown by main() in surface-brief.mjs when the 'path' subcommand is invoked without a concrete target argument. surfaceBriefPathForTarget(target, ...) returns a falsy value when target is empty/undefined (it cannot derive a brief filename without one), and the CLI refuses to guess. The 'list' subcommand intentionally needs no target; 'path', 'read', and 'write' do.","triggerScenarios":"The script is run as 'surface-brief.mjs path' (no target), or 'surface-brief.mjs path \"\"' (empty target). The destructuring at the top sets target = argv[1]; if absent it is undefined and surfaceBriefPathForTarget returns null.","commonSituations":"User runs the path subcommand to discover where a brief would live but forgets to name the target; a wrapper script passes an unset variable as the target; confusion with 'list' which needs no target.","solutions":["Pass a target identifier: 'surface-brief.mjs path src/components/Header.jsx'.","If you wanted to enumerate existing briefs instead, use 'surface-brief.mjs list'.","Ensure wrapper scripts pass a non-empty target variable."],"exampleFix":"# before\nnode surface-brief.mjs path\n# after\nnode surface-brief.mjs path src/components/Header.jsx","handlingStrategy":"validation","validationCode":"if (command === 'path' && (!target || target === '')) {\n  throw new Error('path subcommand requires a target argument');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap the CLI in a shell function that requires the target for 'path/read/write'.","Print the usage line to stderr before throwing so users see the fix inline.","Prefer 'list' when enumerating; require 'path' only when materializing a filename."],"tags":["cli","surface-brief","argument-parsing","target"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}