{"record":{"id":"d8d58a51b949ff2b","repo":"davila7/claude-code-templates","slug":"invalid-workflow-hash-format-expected-format-ha","errorCode":null,"errorMessage":"Invalid workflow hash format. Expected format: #hash","messagePattern":"Invalid workflow hash format\\. Expected format: #hash","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"cli-tool/src/index.js","lineNumber":2053,"sourceCode":"  \n  console.log(chalk.blue('Examples:'));\n  console.log(chalk.gray('  cct --agent api-security-audit'));\n  console.log(chalk.gray('  cct --agent deep-research-team/academic-researcher'));\n  console.log('');\n}\n\n/**\n * Install workflow from hash\n */\nasync function installWorkflow(workflowHash, targetDir, options) {\n  console.log(chalk.blue(`🔧 Installing workflow from hash: ${workflowHash}`));\n  \n  try {\n    // Extract hash from format #hash\n    const hash = workflowHash.startsWith('#') ? workflowHash.substring(1) : workflowHash;\n    \n    if (!hash || hash.length < 3) {\n      throw new Error('Invalid workflow hash format. Expected format: #hash');\n    }\n    \n    console.log(chalk.gray(`📥 Fetching workflow configuration...`));\n    \n    // Fetch workflow configuration from a remote service\n    // For now, we'll simulate this by using a local storage approach\n    // In production, this would fetch from a workflow registry\n    const workflowData = await fetchWorkflowData(hash);\n    \n    if (!workflowData) {\n      throw new Error(`Workflow with hash \"${hash}\" not found. Please check the hash and try again.`);\n    }\n    \n    console.log(chalk.green(`✅ Workflow found: ${workflowData.name}`));\n    console.log(chalk.cyan(`📝 Description: ${workflowData.description}`));\n    console.log(chalk.cyan(`🏷️  Tags: ${workflowData.tags.join(', ')}`));\n    console.log(chalk.cyan(`📊 Steps: ${workflowData.steps.length}`));\n    ","sourceCodeStart":2035,"sourceCodeEnd":2071,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-tool/src/index.js#L2035-L2071","documentation":"Thrown when parsing a workflow share-hash: the CLI strips a leading '#', and if the remainder is empty or shorter than 3 characters it rejects the input before attempting any fetch/decode. This guards against malformed share links like `#` or `#ab`.","triggerScenarios":"Running the workflow-from-hash command with `#ab`, `#`, an empty string, or a hash of only 1-2 characters. Any value whose post-# length is <3 throws immediately.","commonSituations":"Truncated or typo'd share link pasted from the dashboard; user pastes only the '#' prefix; whitespace-stripped hash from messaging apps.","solutions":["Copy the full share hash from the dashboard share dialog (format #hash, typically much longer)","Ensure no characters were truncated when copying/pasting","If the hash contains '_', keep the encoded payload intact — do not edit it","Pass at least 3 characters after the '#'"],"exampleFix":"// before\ninstallFromHash('#ab'); // throws\n// after\ninstallFromHash('#a1b2c3_dEf...'); // full hash from dashboard","handlingStrategy":"validation","validationCode":"const h = workflowHash.replace(/^#/, '').trim();\nif (!h || h.length < 3) {\n  console.error('Hash must be at least 3 chars after \"#\" — copy the full share link');\n  process.exit(1);\n}","typeGuard":"function isValidWorkflowHash(input) {\n  const h = input.startsWith('#') ? input.slice(1) : input;\n  return typeof input === 'string' && h.length >= 3;\n}","tryCatchPattern":null,"preventionTips":["Copy hashes with the dashboard share button, not manual text selection","Validate length before invoking the CLI","Avoid trimming the hash beyond whitespace"],"tags":["validation","workflow-hash","input-format","cli"],"backgroundTag":"invalid-share-link-hash","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}