{"record":{"id":"ce4a57e83dd36f9e","repo":"ruvnet/ruflo","slug":"label-must-be-non-empty","errorCode":null,"errorMessage":"${label} must be non-empty","messagePattern":"(.+?) must be non-empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/harness/build-evidence.ts","lineNumber":55,"sourceCode":"  path: string;\n}\n\nexport interface BuildEvidence {\n  contractVersion: 1;\n  assurance: 'declared-unsigned';\n  sourceStateId: string;\n  buildInputs: readonly DeclaredBuildInput[];\n  toolchains: readonly DeclaredToolchain[];\n  evidenceDigest: string;\n}\n\nfunction compare(left: string, right: string): number {\n  return left < right ? -1 : left > right ? 1 : 0;\n}\n\nfunction requireText(value: string, label: string): string {\n  const result = value.trim();\n  if (!result) throw new Error(`${label} must be non-empty`);\n  return result;\n}\n\nfunction requireDigest(value: string, label: string): string {\n  if (!DIGEST.test(value)) throw new Error(`${label} must be a canonical sha256 digest`);\n  return value;\n}\n\nfunction normalizePath(value: string): string {\n  const path = requireText(value, 'build input path');\n  if (\n    path.includes('\\\\')\n    || path.startsWith('/')\n    || path.startsWith('-')\n    || path !== path.normalize('NFC')\n    || path.split('/').some((part) => !part || part === '.' || part === '..')\n  ) {\n    throw new Error(`unsafe build input path: ${value}`);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/harness/build-evidence.ts#L37-L73","documentation":"createBuildEvidence trims every declared string — build input name, build input path (via normalizePath), toolchain name, and toolchain version — and throws when the trimmed result is empty. The label in the message identifies the exact field that failed (e.g. 'build input name must be non-empty').","triggerScenarios":"A DeclaredBuildInput or ToolchainDeclaration whose name or version is '', ' ', or whitespace-only; a build input path that is blank (fails before the unsafe-path checks run).","commonSituations":"Optional string fields left as '' instead of omitted; declaration objects built from missing keys; placeholders like 'TODO' removed by a trim before the call; config generators emitting blank rows for skipped entries.","solutions":["Check the label in the message to identify which declaration field is blank","Populate the field or remove the empty declaration entirely — empty arrays are accepted, blank entries are not","When generating declarations programmatically, trim and assert non-empty at the source that builds them"],"exampleFix":"// before\nconst buildInputs = [\n  { name: '   ', path: 'dist/app.js', digest: d, bytes: 1024 }, // blank name\n];\n\n// after\nconst buildInputs = [\n  { name: 'app-bundle', path: 'dist/app.js', digest: d, bytes: 1024 },\n];","handlingStrategy":"validation","validationCode":"function validateDeclarations(inputs: { name: string }[], tools: { name: string; version: string }[]): void {\n  for (const i of inputs) if (!i.name.trim()) throw new Error('build input name is blank');\n  for (const t of tools) {\n    if (!t.name.trim()) throw new Error('toolchain name is blank');\n    if (!t.version.trim()) throw new Error('toolchain version is blank');\n  }\n}","typeGuard":null,"tryCatchPattern":"Catch around createBuildEvidence/captureBuildEvidence and map the '<label> must be non-empty' message back to the offending declaration index so users see which entry (not just which field) is blank.","preventionTips":["Make declaration fields required (non-optional strings) in your own types so blanks fail type-check","Trim at the boundary where declarations are authored or deserialized","Reject blank rows during config load with row context instead of at evidence hashing"],"tags":["build-evidence","validation","harness","empty-string"],"backgroundTag":"empty-required-field","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}