agalwood/Motrix · error · FsSandboxError

plugin.fs.invalid_basename

plugin.fs.invalid_basename

Error message

not a valid basename: ${name}

What it means

Thrown by `assertBasename(name)` when the proposed filename is empty, `.`, `..`, contains a `/` or `\`, or starts with a `.`. The function enforces a safe single-segment name (no traversal, no hidden files). Code is `plugin.fs.invalid_basename`. Used by rename() and any path expecting a bare filename.

Source

Thrown at src/core/plugin/capabilities/fs-sandbox.ts:145

  ) {
    throw new FsSandboxError(
      'plugin.fs.path_outside_sandbox',
      'plugin.fs.path_outside_sandbox: resolved path outside sandbox root'
    )
  }
  return normalizedAbs
}

export function assertBasename(name: string): void {
  if (
    name === '' ||
    name === '.' ||
    name === '..' ||
    name.includes('/') ||
    name.includes('\\') ||
    name.startsWith('.')
  ) {
    throw new FsSandboxError(
      'plugin.fs.invalid_basename',
      `not a valid basename: ${name}`
    )
  }
}

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Sanitize the input: take `path.basename()`, strip a leading dot, and reject empty results.
  2. Validate against an explicit allow pattern (e.g. `/^[A-Za-z0-9._-]+$/` and disallow leading dot).
  3. Refuse separators and the literal `.`/`..` tokens before calling rename().
  4. If dotfiles are legitimately needed, file a feature request rather than working around the guard.

Example fix

// before
await task.rename('logs/2024.txt') // contains '/', rejected

// after — pass a bare basename
await task.rename('2024.txt')
Defensive patterns

Strategy: validation

Validate before calling

function assertSafeBasename(name: string): void {
  if (
    name === '' || name === '.' || name === '..' ||
    name.includes('/') || name.includes('\\') || name.startsWith('.')
  ) {
    throw new Error(`unsafe basename: ${name}`)
}
}

Type guard

function isInvalidBasename(e: unknown): boolean {
  return e instanceof Error && (e as FsSandboxError).code === 'plugin.fs.invalid_basename'
}

Try / catch

try {
  await task.rename(newFilename)
} catch (e) {
  if (isInvalidBasename(e)) { /* sanitize and retry */ }
  else throw e
}

Prevention

When it happens

Trigger: Passing a path-like string (with separators), a dotfile (`.env`), the special entries `.`/`..`, or an empty string to a function that requires a plain basename. Most commonly hit via `FsTask.rename(newFilename)`.

Common situations: Plugin derives a filename from user input without sanitizing; allowing dotfiles by mistake; passing a full relative path instead of just a name; cross-platform code where a `\` slips in from Windows input.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/1b5585c0f7b98148. Report an issue: GitHub.