affaan-m/ECC · error · Error

Structured session targets require a non-empty string value

Error message

Structured session targets require a non-empty string value

What it means

coerceTargetValue() inside the adapter registry rejects a structured target whose `value` is not a non-empty string. normalizeStructuredTarget routes object-shaped targets through coerceTargetValue before mapping them to a prefixed target string, so { type: ..., value } must carry a trimmed non-empty value. Non-object targets bypass this check and are returned as-is.

Source

Thrown at scripts/lib/session-adapters/registry.js:46

    ...sharedOptions,
    ...(options.adapterOptions && options.adapterOptions[adapterId]
      ? options.adapterOptions[adapterId]
      : {})
  };
}

function createDefaultAdapters(options = {}) {
  return [
    createClaudeHistoryAdapter(buildDefaultAdapterOptions(options, 'claude-history')),
    createDmuxTmuxAdapter(buildDefaultAdapterOptions(options, 'dmux-tmux')),
    createCodexWorktreeAdapter(buildDefaultAdapterOptions(options, 'codex-worktree')),
    createOpencodeAdapter(buildDefaultAdapterOptions(options, 'opencode'))
  ];
}

function coerceTargetValue(value) {
  if (typeof value !== 'string' || value.trim().length === 0) {
    throw new Error('Structured session targets require a non-empty string value');
  }

  return value.trim();
}

function normalizeStructuredTarget(target, context = {}) {
  if (!target || typeof target !== 'object' || Array.isArray(target)) {
    return {
      target,
      context: { ...context }
    };
  }

  const value = coerceTargetValue(target.value);
  const type = typeof target.type === 'string' ? target.type.trim() : '';
  if (type.length === 0) {
    throw new Error('Structured session targets require a non-empty type');
  }

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Validate value before constructing the structured target: if (!value || typeof value !== 'string') throw a clearer error or fall back to a string target.
  2. Coerce to a trimmed string and reject empty: value = String(value||'').trim(); if (!value) throw new Error('target value required').
  3. Prefer passing a plain string target (e.g. 'claude:<id>') when you already have the value; structured form is optional.
  4. In UI/CLI, disable submit until value is non-empty.

Example fix

// before
registry.select({ type: 'opencode', value: userInput.value }, context); // userInput.value is ''

// after
const value = (userInput.value || '').trim();
if (!value) throw new Error('A session target value is required');
registry.select({ type: 'opencode', value }, context);
// or simply pass a string
registry.select(`opencode:${value}`, context);
Defensive patterns

Strategy: validation

Validate before calling

function coerceStructuredTarget(target) {
  if (!target || typeof target !== 'object' || Array.isArray(target)) return target;
  const value = typeof target.value === 'string' ? target.value.trim() : '';
  if (!value) throw new Error('Structured session target requires a non-empty value');
  return { ...target, value };
}
// then: registry.select(coerceStructuredTarget(target), context);

Type guard

function isStructuredTarget(t) {
  return t !== null && typeof t === 'object' && !Array.isArray(t)
    && typeof t.value === 'string' && t.value.trim().length > 0;
}

Try / catch

try { registry.select(target, context); }
catch (err) {
  if (err.message === 'Structured session targets require a non-empty string value') {
    // fall back to a plain string target, or surface a friendly UI error
    throw new Error('Please provide a non-empty session target value.');
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling adapter registry .select() (or open/normalize) with target = { type: 'claude-history', value: '' } or { type: 'opencode', value: null } or { type: 'codex', value: 42 }. Programmatically building a structured target from user input without validating the value field.

Common situations: A CLI form that lets a user pick a target type but leave the value blank. A wrapper that constructs { type, value } from separate inputs where value came back undefined. Migrating from string targets to structured targets and forgetting to default value to an empty string that slips through.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/22874c8b975d241a. Report an issue: GitHub.