Yeachan-Heo/oh-my-codex · error · Error
`target` is required
Error message
`target` is required
What it means
The tmux-hook config lacks a valid `target` object, which tells the hook which tmux session/pane to inject into. It must be present, an object (not null/array/string), to pass validation.
Source
Thrown at src/cli/tmux-hook.ts:119
function tmuxHookStatePath(cwd = process.cwd()): string {
return join(omxDir(cwd), 'state', 'tmux-hook-state.json');
}
function tmuxHookLogPath(cwd = process.cwd()): string {
return join(omxDir(cwd), 'logs', `tmux-hook-${new Date().toISOString().split('T')[0]}.jsonl`);
}
function parseConfig(raw: unknown): TmuxHookConfig {
if (!raw || typeof raw !== 'object') {
throw new Error('tmux-hook config must be a JSON object');
}
const parsed = raw as Record<string, unknown>;
if (parsed.enabled !== true && parsed.enabled !== false) {
throw new Error('`enabled` must be boolean');
}
const target = parsed.target;
if (!target || typeof target !== 'object') {
throw new Error('`target` is required');
}
const targetObj = target as Record<string, unknown>;
if (targetObj.type !== 'session' && targetObj.type !== 'pane') {
throw new Error('`target.type` must be "session" or "pane"');
}
if (typeof targetObj.value !== 'string' || targetObj.value.trim() === '') {
throw new Error('`target.value` must be a non-empty string');
}
const allowedModes = parsed.allowed_modes;
if (!Array.isArray(allowedModes) || allowedModes.length === 0 || allowedModes.some(v => typeof v !== 'string')) {
throw new Error('`allowed_modes` must be a non-empty string array');
}
const cooldown = parsed.cooldown_ms;
const maxInjections = parsed.max_injections_per_session;
if (typeof cooldown !== 'number' || cooldown < 0 || !Number.isFinite(cooldown)) {
throw new Error('`cooldown_ms` must be a non-negative number');View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Add "target": {"type": "session"|"pane", "value": "..."}
- Regenerate the config with omx tmux-hook init and edit values
- Check the schema in the docs for required keys
Example fix
// before
{"enabled": true}
// after
{"enabled": true, "target": {"type": "session", "value": "omx"}} Defensive patterns
Strategy: type-guard
Validate before calling
const ok = cfg.target && typeof cfg.target === 'object' && !Array.isArray(cfg.target);
if (!ok) throw new Error('target object required'); Type guard
function hasTarget(v: unknown): v is { target: Record<string, unknown> } {
return typeof v === 'object' && v !== null && typeof (v as any).target === 'object' && (v as any).target !== null;
} Try / catch
try { await loadConfig(); } catch (e) { if (e instanceof Error && e.message.includes('`target`')) { addTargetAndRetry(); } } Prevention
- Always scaffold with omx tmux-hook init then edit incrementally
- Keep required keys in a checklist when hand-writing config
When it happens
Trigger: Config omits `target`, sets it to null, a string, or an array. Any falsy or non-object value triggers this before type/value checks run.
Common situations: Minimal configs copied from docs that only set enabled; refactors that renamed the key (e.g. session instead of target).
Related errors
- tmux-hook config must be a JSON object
- `enabled` must be boolean
- `target.type` must be "session" or "pane"
- `target.value` must be a non-empty string
- `allowed_modes` must be a non-empty string array
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/ef0ed1f5700fe4ff.
Report an issue: GitHub.