affaan-m/ECC · error · Error

empty stdin

Error message

empty stdin

What it means

ck save reads its session payload as JSON from stdin; when the raw stdin is empty (or whitespace only) it throws 'empty stdin', which the surrounding catch reports as 'invalid JSON on stdin' along with the expected schemas and exits 1. The script requires the caller to pipe a complete JSON document.

Solutions

  1. Pipe a JSON document matching the save schema into the command, e.g. echo '{"summary":"...","leftOff":"...","nextSteps":[],"decisions":[],"blockers":[]}' | node skills/ck/commands/save.mjs
  2. If using --init, pipe the init schema instead ({"name","path","description","stack","goal","constraints"})
  3. Check the upstream producer in your pipeline — fix why it emitted no output
  4. For interactive testing, use `cat payload.json | node save.mjs` rather than running bare

Example fix

// before (nothing on stdin)
$ node save.mjs

// after
$ cat session.json | node save.mjs   # session.json: {"summary":"...","leftOff":"...","nextSteps":["..."],"decisions":[],"blockers":[]}
Defensive patterns

Strategy: validation

Validate before calling

const raw = readFileSync(0, 'utf8').trim();
if (!raw) { console.error('ck save: no JSON received on stdin'); process.exit(1); }
JSON.parse(raw);

Try / catch

let input; try { input = JSON.parse(readFileSync(0,'utf8')); } catch { /* print schema and exit 1 */ }

Prevention

When it happens

Trigger: Running `node skills/ck/commands/save.mjs` interactively without piping input; the upstream command in a pipe produced no output (e.g. a failed hook or empty transcript); redirecting from an empty file.

Common situations: Hook configured to pipe session data but the generator emitted nothing; running the script manually in a terminal and typing nothing before Ctrl-D; a previous pipeline stage crashed silently leaving stdin empty.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/b85403a837650af0. Report an issue: GitHub.

Appendix: source

Thrown at skills/ck/commands/save.mjs:34

 * exit 0: success  exit 1: error
 */

import { readFileSync, mkdirSync, writeFileSync } from 'fs';
import { resolve } from 'path';
import {
  readProjects, writeProjects, loadContext, saveContext,
  today, shortId, gitSummary, nativeMemoryDir,
  CURRENT_SESSION,
} from './shared.mjs';

const isInit = process.argv.includes('--init');
const cwd    = process.env.PWD || process.cwd();

// ── Read JSON from stdin ──────────────────────────────────────────────────────
let input;
try {
  const raw = readFileSync(0, 'utf8').trim();
  if (!raw) throw new Error('empty stdin');
  input = JSON.parse(raw);
} catch (e) {
  console.error(`ck save: invalid JSON on stdin — ${e.message}`);
  console.log('Expected schema (save):  {"summary":"...","leftOff":"...","nextSteps":["..."],"decisions":[{"what":"...","why":"..."}],"blockers":["..."]}');
  console.log('Expected schema (--init): {"name":"...","path":"...","description":"...","stack":["..."],"goal":"...","constraints":["..."]}');
  process.exit(1);
}

// ─────────────────────────────────────────────────────────────────────────────
// INIT MODE: first-time project registration
// ─────────────────────────────────────────────────────────────────────────────
if (isInit) {
  const { name, path: projectPath, description, stack, goal, constraints, repo } = input;

  if (!name || !projectPath) {
    console.log('ck init: name and path are required.');
    process.exit(1);
  }

View on GitHub (pinned to 8321021c54)