with one click
errors
Error Handling skill for the ikigai project
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Error Handling skill for the ikigai project
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Automated quality check loops with escalation and fix sub-agents
JSON-based end-to-end test format, runner, and mock provider
Jujutsu (jj) skill for the ikigai project
How to write effective Ralph goals for Ikigai-driven workflows
Create and manage Ralph goals from Ikigai using the real ralph-pipeline scripts
Create repositories using the real ralph-pipeline repo-create script
| name | errors |
| description | Error Handling skill for the ikigai project |
| Mechanism | When | Compiles Out? |
|---|---|---|
res_t | IO, parsing, external failures | No |
assert() | Preconditions, contracts | Yes (-DNDEBUG) |
PANIC() | OOM, corruption, impossible states | No |
PANIC()res_tassert()PANIC()_ptr suffix)typedef struct {
union { void *ok; err_t *err; };
bool is_err;
} res_t;
typedef struct err {
err_code_t code;
const char *file;
int32_t line;
char msg[256];
} err_t;
| Code | Value | Usage |
|---|---|---|
OK | 0 | Success/no error |
ERR_INVALID_ARG | 1 | Invalid argument validation |
ERR_OUT_OF_RANGE | 2 | Out of range values |
ERR_IO | 3 | File operations, config loading |
ERR_PARSE | 4 | JSON/protocol parsing |
ERR_DB_CONNECT | 5 | Database connection failures |
ERR_DB_MIGRATE | 6 | Database migration failures |
ERR_OUT_OF_MEMORY | 7 | Memory allocation failures |
ERR_AGENT_NOT_FOUND | 8 | Agent not found in array |
ERR_PROVIDER | 9 | Provider error |
ERR_MISSING_CREDENTIALS | 10 | Missing credentials |
ERR_NOT_IMPLEMENTED | 11 | Not implemented |
OK(value) / ERR(ctx, CODE, "msg", ...) - Create resultsTRY(expr) - Extract value or return errorCHECK(res) - Propagate error if failedis_ok(&res) / is_err(&res) - InspectBuild behavior:
debug build (default): asserts are ACTIVE → violation triggers SIGABRTrelease build (-DNDEBUG): asserts are COMPILED OUT → violation causes undefined behavior (segfault, corruption, etc.)We normally run debug builds. When you see assert(x) fail, expect SIGABRT, not a segfault.
Guidelines:
// LCOV_EXCL_BR_LINE// OOM - most common
if (ptr == NULL) PANIC("Out of memory"); // LCOV_EXCL_BR_LINE
// Switch default
default: PANIC("Invalid state"); // LCOV_EXCL_LINE
// Corruption
if (size > capacity) PANIC("Array corruption"); // LCOV_EXCL_LINE
res_t, never crashassert() preconditions, trust caller validated#ifndef NDEBUG + tcase_add_test_raise_signal(tc, test, SIGABRT)tcase_add_test_raise_signal(tc, test, SIGABRT) (all builds)| Code | Marker |
|---|---|
| Assertions | // LCOV_EXCL_BR_LINE |
| OOM checks | // LCOV_EXCL_BR_LINE |
| PANIC logic errors | // LCOV_EXCL_LINE |
New exclusions require updating LCOV_EXCL_COVERAGE in Makefile.
THE TRAP: Errors allocated on a context that gets freed become use-after-free bugs.
// BROKEN - error is allocated on foo, then foo is freed
res_t ik_foo_init(void *parent, foo_t **out) {
foo_t *foo = talloc_zero_(parent, sizeof(foo_t));
res_t result = ik_bar_init(foo, &foo->bar); // Error allocated on foo
if (is_err(&result)) {
talloc_free(foo); // FREES THE ERROR TOO!
return result; // USE-AFTER-FREE CRASH
}
}
THE FIX: Error allocation context must survive the error's return. Either:
Option A (Preferred): Pass parent to sub-functions for error allocation:
res_t ik_foo_init(void *parent, foo_t **out) {
bar_t *bar = NULL;
res_t result = ik_bar_init(parent, &bar); // Error on parent - survives!
if (is_err(&result)) return result;
foo_t *foo = talloc_zero_(parent, sizeof(foo_t));
talloc_steal(foo, bar);
foo->bar = bar;
*out = foo;
}
Option B (Band-aid): Reparent error before freeing context:
res_t ik_foo_init(void *parent, foo_t **out) {
foo_t *foo = talloc_zero_(parent, sizeof(foo_t));
res_t result = ik_bar_init(foo, &foo->bar);
if (is_err(&result)) {
talloc_steal(parent, result.err); // Save error to survivor
talloc_free(foo);
return result;
}
}
Rule: When returning an error after freeing a context:
Reference: See fix.md and project/error_handling.md#error-context-lifetime-critical for detailed analysis.
Full details: project/return_values.md, project/error_handling.md, project/error_patterns.md, project/error_testing.md