Hmbown/CodeWhale · critical · Error
self-verify failed
Error message
self-verify failed: ${check.errors.join("; ")} What it means
After constructing the envelope, buildEnvelope immediately verifies it against the derived public key via verifyEnvelope. If that self-verification fails, this error aggregates the verifier's error list. It is an internal safety net: a produced envelope that cannot be verified is never returned to the caller.
Solutions
- Read the joined check.errors in the message to see which verification rule failed
- Regenerate or re-export the signing key and confirm createPrivateKey yields an Ed25519 key
- Sign a trivial payload to isolate whether the problem is the key or the payload fields
- If you modified this script, diff buildEnvelope and verifyEnvelope against git HEAD
Example fix
// before
const key = createPrivateKey(fs.readFileSync(process.env.KEY_PATH));
await buildEnvelope({ privateKey: key, keyId, payload });
// after
const key = createPrivateKey({ key: fs.readFileSync(process.env.KEY_PATH), format: 'pem' });
if (key.asymmetricKeyType !== 'ed25519') throw new Error('need Ed25519 key');
await buildEnvelope({ privateKey: key, keyId, payload }); Defensive patterns
Strategy: try-catch
Validate before calling
const key = createPrivateKey({ key: pem, format: 'pem' });
if (key.asymmetricKeyType !== 'ed25519') throw new Error('signing key must be Ed25519 before envelope build'); Type guard
const isEd25519Private = (k) => { try { return createPrivateKey(k).asymmetricKeyType === 'ed25519'; } catch { return false; } }; Try / catch
try { env = buildEnvelope({ privateKey, keyId, payload }); } catch (e) { if (e.message.startsWith('self-verify failed')) { console.error('Envelope failed self-verify:', e.message); process.exit(3); } throw e; } Prevention
- Verify your private key parses as Ed25519 before every publish run
- Do not modify buildEnvelope/verifyEnvelope locally without running the script's tests
- Sign a canary payload after key rotation to confirm key health
- Treat any self-verify failure as a bug, not retryable input
When it happens
Trigger: buildEnvelope produced an envelope that verifyEnvelope rejects — e.g. signature mismatch (wrong/unsupported private key), a payload field the verifier considers invalid, or the not_after/version fields breaking verification invariants.
Common situations: Passing a corrupted or wrong-format private key whose derived public key does not match the signature; tampered buildEnvelope/verifyEnvelope code after local edits; key object that is not a usable Ed25519 private key despite parsing.
Related errors
- active plugin registry is missing its pre-dotenv…
- bad channel slug
- bounded to model output cap
- Claimed delayed trigger has no durable task binding
- Cloud agent produced no branch head to raise.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/8ef5a378117d57b4.
Report an issue: GitHub.
Appendix: source
Thrown at web/scripts/facts-publish.mjs:318
const sha256 = createHash("sha256").update(payloadBytes).digest("hex");
const envelope = {
envelope: ENVELOPE_VERSION,
channel: payload.channel,
facts_version: payload.facts_version,
schema_version: payload.schema_version,
key_id: keyId,
alg: "ed25519",
applies_to: payload.applies_to,
published_at: payload.published_at,
payload_b64: payloadBytes.toString("base64"),
sig_b64: sig.toString("base64"),
sigs: [],
sha256,
};
if (payload.not_after != null) envelope.not_after = payload.not_after;
const pub = rawPublicKeyFromKeyObject(createPublicKey(privateKey)).toString("base64");
const check = verifyEnvelope(envelope, pub);
if (!check.ok) throw new Error(`self-verify failed: ${check.errors.join("; ")}`);
return envelope;
}
// ---------------------------------------------------------------------------
// CLI helpers
// ---------------------------------------------------------------------------
function parseArgs(argv) {
const positional = [];
const flags = {};
for (let i = 0; i < argv.length; i += 1) {
const arg = argv[i];
if (arg.startsWith("--")) {
const key = arg.slice(2);
const next = argv[i + 1];
if (next === undefined || next.startsWith("--")) flags[key] = true;
else { flags[key] = next; i += 1; }
} else positional.push(arg);View on GitHub (pinned to 433685b202)