Yeachan-Heo/oh-my-codex · error · Error
`target.value` must be a non-empty string
Error message
`target.value` must be a non-empty string
What it means
The config's target.value (the session name or pane id to target) must be a non-empty string. Whitespace-only strings also fail because of the .trim() check.
Source
Thrown at src/cli/tmux-hook.ts:126
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');
}
if (typeof maxInjections !== 'number' || maxInjections < 1 || !Number.isFinite(maxInjections)) {
throw new Error('`max_injections_per_session` must be >= 1');
}
const promptTemplate = parsed.prompt_template;
const marker = parsed.marker;View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Set value to a real session name or pane id string, e.g. "%5" or "main-session"
- Quote numeric ids: "3" not 3
- Run tmux list-sessions / list-panes to get the exact identifier
Example fix
// before
{"target": {"type": "pane", "value": 3}}
// after
{"target": {"type": "pane", "value": "%3"}} Defensive patterns
Strategy: validation
Validate before calling
const v = cfg.target?.value;
if (typeof v !== 'string' || v.trim() === '') throw new Error('bad target.value'); Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.trim() !== '';
Try / catch
try { await loadConfig(); } catch (e) { if (e instanceof Error && e.message.includes('target.value')) fixValue(); } Prevention
- Quote pane ids in JSON: "%3" not 3
- Get exact ids from tmux list-panes / list-sessions
When it happens
Trigger: "value": "", "value": " ", value set to a number (e.g. pane id 3 without quotes), or the key missing so it is undefined.
Common situations: Numeric tmux pane ids written as JSON numbers instead of strings; empty template placeholders never filled in.
Related errors
- `prompt_template` must be a non-empty string
- `marker` must be a non-empty string
- tmux-hook config must be a JSON object
- `enabled` must be boolean
- `target` is required
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/55afe8a362093cee.
Report an issue: GitHub.