KeygraphHQ/shannon · error · Error
Cannot create deliverables directory at ${deliverablesDir}
Error message
Cannot create deliverables directory at ${deliverablesDir} What it means
Thrown by saveDeliverableFile in save-deliverable when mkdirSync(deliverablesDir, { recursive: true }) throws. The target directory is <targetDir>/<SHANNON_DELIVERABLES_SUBDIR or '.shannon/deliverables'>; failure is typically permissions, a read-only mount, or disk full. Surfaced by main() as a JSON error with retryable:true and exit code 1, because filesystem errors are often transient.
Source
Thrown at apps/worker/src/scripts/save-deliverable.ts:87
args.filePath = next;
i++;
}
}
return args;
}
// === File Operations ===
function saveDeliverableFile(targetDir: string, filename: string, content: string): string {
const subdir = process.env.SHANNON_DELIVERABLES_SUBDIR || '.shannon/deliverables';
const deliverablesDir = join(targetDir, ...subdir.split('/'));
const filepath = join(deliverablesDir, filename);
try {
mkdirSync(deliverablesDir, { recursive: true });
} catch {
throw new Error(`Cannot create deliverables directory at ${deliverablesDir}`);
}
writeFileSync(filepath, content, 'utf8');
return filepath;
}
// === Main ===
function main(): void {
if (process.argv.includes('--help') || process.argv.includes('-h')) {
printHelp();
return;
}
const args = parseArgs(process.argv);
// 1. Validate --type
if (!args.type) {View on GitHub (pinned to 1ae0a142f8)
Solutions
- Ensure the worker process has write permission on targetDir and the resolved subdir (chown/chmod as needed).
- If SHANNON_DELIVERABLES_SUBDIR is set, verify it resolves to a writable location inside the mount.
- On Linux, run the worker container with a UID matching the repo owner, or chmod the repo to be group-writable.
- Retry the workflow - the error is marked retryable and may clear transient FS issues.
- Check disk space on the host.
Example fix
# before - worker cannot write to repo docker run --rm -u 1000:1000 -v "$PWD/repo:/repo" ... save-deliverable ... # fixes # (a) match the repo owner's UID: docker run --rm -u "$(id -u):$(id -g)" -v "$PWD/repo:/repo" ... # (b) or make the repo group-writable: chmod -R g+w repo/ # (c) or redirect deliverables to a writable mount: export SHANNON_DELIVERABLES_SUBDIR="_tmp/deliverables"
Defensive patterns
Strategy: try-catch
Validate before calling
import { access, constants } from 'node:fs';
async function isDirWritable(dir: string): Promise<boolean> {
try {
await access(dir, constants.W_OK);
return true;
} catch {
return false;
}
} Try / catch
try {
const filepath = saveDeliverableFile(targetDir, filename, content);
} catch (e) {
if (e instanceof Error && /Cannot create deliverables directory/.test(e.message)) {
// log retryable FS error, surface to Temporal for retry, or chmod/remount
} else throw e;
} Prevention
- Run the worker container with a UID matching the repo owner (or group-writable repo).
- Verify SHANNON_DELIVERABLES_SUBDIR resolves to a writable location inside the mount.
- Check host disk space before launching long scans.
- Keep the repo on a writable volume; do not mount it read-only.
When it happens
Trigger: save-deliverable runs (worker persists a deliverable) and mkdirSync fails on the resolved deliverables directory - e.g. targetDir is read-only, the path crosses a read-only mount, the process lacks write permission, or the disk is full. SHANNON_DELIVERABLES_SUBDIR can redirect the location.
Common situations: Worker container runs as a UID without write access to the mounted repo (Linux permission mismatch); SHANNON_DELIVERABLES_SUBDIR points at a read-only volume; disk-full CI runner; macOS/Windows filesystem case collision on '.shannon'.
Related errors
- Failed to write final report: ${err.message}
- CONFIG_NOT_FOUND
- DELIVERABLE_NOT_FOUND
- CONFIG_VALIDATION_FAILED
- TOTP secret is empty after cleaning
AI-assisted analysis of KeygraphHQ/shannon@1ae0a142f8 (2026-08-12).
Data as JSON: /api/errors/c73e20a3664ee95d.
Report an issue: GitHub.