KeygraphHQ/shannon · error · PentestError

Prompt file not found: ${promptPath}

Error message

Prompt file not found: ${promptPath}

What it means

Thrown by loadPrompt when the prompt template file at <promptsDir>/<promptName>.txt does not exist (fs.pathExists returns false). promptsDir is resolvePromptDir(promptDir), optionally suffixed with /pipeline-testing when pipeline-testing mode is on. Category 'prompt', non-retryable. Triggered by an unknown agent name, a wrong promptDir override, or pipeline-testing mode pointing at a subdir lacking the file.

Source

Thrown at apps/worker/src/services/prompt-manager.ts:473

export async function loadPrompt(
  promptName: string,
  variables: PromptVariables,
  config: DistributedConfig | null = null,
  pipelineTestingMode: boolean = false,
  logger: ActivityLogger,
  promptDir?: string,
): Promise<string> {
  try {
    const basePromptsDir = resolvePromptDir(promptDir);
    const promptsDir = pipelineTestingMode ? path.join(basePromptsDir, 'pipeline-testing') : basePromptsDir;
    const promptPath = path.join(promptsDir, `${promptName}.txt`);

    if (pipelineTestingMode) {
      logger.info(`Using pipeline testing prompt: ${promptPath}`);
    }

    if (!(await fs.pathExists(promptPath))) {
      throw new PentestError(`Prompt file not found: ${promptPath}`, 'prompt', false, { promptName, promptPath });
    }

    // 2. Assign Playwright session based on agent name
    const enhancedVariables: PromptVariables = { ...variables };

    const session = PLAYWRIGHT_SESSION_MAPPING[promptName as keyof typeof PLAYWRIGHT_SESSION_MAPPING];
    if (session) {
      enhancedVariables.PLAYWRIGHT_SESSION = session;
      logger.info(`Assigned ${promptName} -> ${enhancedVariables.PLAYWRIGHT_SESSION}`);
    } else {
      enhancedVariables.PLAYWRIGHT_SESSION = 'agent1';
      logger.warn(`Unknown agent ${promptName}, using fallback -> ${enhancedVariables.PLAYWRIGHT_SESSION}`);
    }

    // 3. Read template file
    let template = await fs.readFile(promptPath, 'utf8');

    // 4. Process @include directives

View on GitHub (pinned to 1ae0a142f8)

Solutions

  1. Check context.promptPath on the thrown PentestError for the exact missing file, then confirm it exists in the container/filesystem.
  2. If it is a pipeline-testing run, ensure apps/worker/prompts/pipeline-testing/<name>.txt exists, or drop --pipeline-testing to use the standard prompt.
  3. If you added a new agent, create the prompt template under apps/worker/prompts/ (and pipeline-testing/ if used) and rebuild the image.
  4. If using promptDir override, confirm it resolves (resolvePromptDir) to a tree containing <name>.txt.
  5. Rebuild the local image (./shannon build) or pull the latest npx image so prompts are in sync with the worker code.

Example fix

// before: new agent 'vuln-graphql' registered but no prompt file
//   loadPrompt('vuln-graphql', vars, ...)  -> 'Prompt file not found: .../vuln-graphql.txt'
// after: create the template
//   touch apps/worker/prompts/vuln-graphql.txt  (then author content)
//   ./shannon build
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the prompt file exists for the resolved prompts dir before the workflow runs
import { pathExists } from 'fs-extra';
const promptsDir = pipelineTesting ? path.join(PROMPTS_DIR, 'pipeline-testing') : PROMPTS_DIR;
const promptPath = path.join(promptsDir, `${agentName}.txt`);
if (!(await pathExists(promptPath))) {
  throw new Error(`Missing prompt template for agent '${agentName}': ${promptPath}`);
}

Type guard

function isKnownAgent(name: string): name is AgentName {
  return name in AGENTS;
}

Try / catch

try {
  await loadPrompt(agentName, vars, config, pipelineTesting, logger, promptDir);
} catch (e) {
  if (e instanceof PentestError && /Prompt file not found/.test(e.message)) {
    // either disable pipeline-testing mode, or create/restore the template then rebuild
    const path = (e.context as any)?.promptPath;
    throw new Error(`Restore missing prompt: ${path}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: loadPrompt is called with a promptName that has no corresponding .txt in the resolved prompts directory; pipeline-testing mode is enabled (--pipeline-testing) but apps/worker/prompts/pipeline-testing/<name>.txt is absent; a promptDir override (relative to SHANNON_WORKER_ROOT or absolute) does not contain the named prompt; an agent was added to the registry (AGENTS) but its prompt template was not created.

Common situations: Adding a new agent per the dev guide but forgetting step 2 (create apps/worker/prompts/<name>.txt). Running --pipeline-testing against an image built before the pipeline-testing prompts existed. A custom Docker image that excluded some prompt files. Typo in the agent/prompt name.

Related errors


AI-assisted analysis of KeygraphHQ/shannon@1ae0a142f8 (2026-08-12). Data as JSON: /api/errors/1ee1c30d6bb125a8. Report an issue: GitHub.