Hmbown/CodeWhale · error · Error

bad_args

bad_args

Error message

trajectory id must be a traj-*.jsonl name from trajectory status

What it means

resolveTrajectory validates a user-supplied trajectory id before resolving it to a file inside the plugin's trajectories directory. If the id contains path separators or starts with a dot it is rejected, because ids must be plain traj-*.jsonl filenames listed by trajectory status. This is a guard against path traversal and malformed ids.

Solutions

  1. Run trajectory {action:"status"} and pass the exact id it reports (e.g. 'traj-20260921-....jsonl')
  2. Strip any directory portion and pass only the basename that matches traj-*.jsonl
  3. Pass no id at all (or 'latest') to let resolveTrajectory pick the most recent trajectory

Example fix

// before
run("trajectory", {action:"read", id:"/home/me/.codewhale/trajectories/traj-abc.jsonl"})
// after
run("trajectory", {action:"read", id:"traj-abc.jsonl"})
Defensive patterns

Strategy: validation

Validate before calling

const ok = typeof id === 'string' && /^traj-[^/\\]*\.jsonl$/.test(id) && !id.startsWith('.');
if (!ok) throw new Error('id must be a traj-*.jsonl name from trajectory status');

Type guard

const isTrajectoryId = (v) => typeof v === 'string' && /^traj-[^/\\]*\.jsonl$/.test(v);

Try / catch

try { await run('trajectory', {action:'read', id}) } catch (e) { if (e.code === 'bad_args') console.error('Bad trajectory id:', id); else throw e }

Prevention

When it happens

Trigger: Calling any trajectory action with an id containing '/' or '\\' or beginning with '.' (e.g. '../foo', 'sub/traj-1.jsonl', '.hidden.jsonl', or an absolute path).

Common situations: Pasting a full file path instead of the bare id shown by trajectory status; constructing ids programmatically from directory listings including '.'/'..'; a client cache holding pre-slug ids from an older plugin version.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/7cc23518fe10f3d4. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/trajectory.mjs:85

      });
  } catch { return []; }
}

/**
 * Resolve an id ("latest" or a traj-*.jsonl basename) to a file inside the
 * trajectories dir. Anything that escapes the directory is refused, not read.
 */
export function resolveTrajectory(id) {
  const dir = trajectoriesDir();
  const bad = (message) => Object.assign(new Error(message), { code: "bad_args" });
  const missing = (message) => Object.assign(new Error(message), { code: "trajectory_not_found" });
  let name = typeof id === "string" && id.trim() && id !== "latest" ? id.trim() : null;
  if (!name) {
    const recent = listTrajectories(1);
    if (!recent.length) throw missing("no trajectories on this machine yet — start one with trajectory {action:\"start\"}");
    name = recent[0].id;
  }
  if (name.includes("/") || name.includes("\\") || name.startsWith(".")) throw bad("trajectory id must be a traj-*.jsonl name from trajectory status");
  const file = path.resolve(dir, name);
  if (path.dirname(file) !== path.resolve(dir)) throw bad("trajectory id must stay inside the trajectories directory");
  if (!fs.existsSync(file)) throw missing(`no trajectory named "${name}" (see trajectory {action:"status"})`);
  return file;
}

View on GitHub (pinned to 73e0f67d83)