nocobase/nocobase · error

Refusing to destroy current env "${envName}" without explici

Error message

Refusing to destroy current env "${envName}" without explicit selection in non-interactive mode.
Re-run with `--env ${envName} --force` to destroy this env.

What it means

In `app destroy`, confirmDestroy refuses to proceed in a non-interactive terminal when the current env was not explicitly selected with --env (explicitEnv is false), because destroy would otherwise target an unintended default env. It throws formatDestroyForceRequiredMessage(envName, false): 'Refusing to destroy current env "<name>" without explicit selection in non-interactive mode. Re-run with `--env <name> --force`'.

Source

Thrown at packages/core/cli/src/commands/app/destroy.ts:101

    lines.push('The saved CLI env config will be removed.');
  }

  lines.push(`Type "${runtime.envName}" to confirm:`);
  return lines.join('\n');
}

async function confirmDestroy(
  runtime: ManagedAppRuntime,
  options: {
    explicitEnv: boolean;
    force: boolean;
    removesManagedLocalAppFiles: boolean;
    removesStorageData: boolean;
  },
): Promise<boolean> {
  if (!isInteractiveTerminal()) {
    if (!options.explicitEnv) {
      throw new Error(formatDestroyForceRequiredMessage(runtime.envName, false));
    }
    if (options.force) {
      return true;
    }
    throw new Error(formatDestroyForceRequiredMessage(runtime.envName, options.explicitEnv));
  }

  if (options.force) {
    return true;
  }

  try {
    await input({
      message: buildDestroyPrompt(runtime, options),
      required: true,
      validate: (value) => (value.trim() === runtime.envName ? true : `Type "${runtime.envName}" to confirm.`),
      placeholder: runtime.envName,
    });

View on GitHub (pinned to fa42722fef)

Solutions

  1. Re-run with explicit selection and confirmation: `nocobase app destroy --env <name> --force`.
  2. If interactive destruction is intended, run it in a TTY without flags and answer the prompt.
  3. In CI, parametrize the env name and add --force only after verifying the target env.
  4. Verify which env is 'current' first (`nocobase app list`) to avoid destroying the wrong one.

Example fix

// before (CI, non-interactive)
nocobase app destroy
// after
nocobase app destroy --env staging --force
Defensive patterns

Strategy: validation

Validate before calling

import { isInteractiveTerminal } from './confirm';
const args = process.argv.slice(2);
const isNonInteractive = !isInteractiveTerminal();
if (isNonInteractive && args.includes('destroy') && (!args.includes('--env') || !args.includes('--force'))) {
  throw new Error('Non-interactive destroy requires both --env <name> and --force');
}

Try / catch

try {
  await appDestroy(options);
} catch (error) {
  if ((error as Error).message.includes('Refusing to destroy')) {
    console.error(`Add explicit selection and confirmation: nocobase app destroy --env ${envName} --force`);
  } else throw error;
}

Prevention

When it happens

Trigger: Piping/CI execution (stdin not a TTY) of `nocobase app destroy` without --env, relying on the current/default env, and without --force; the guard also fires when --env is given but --force is missing (second branch with explicitEnv=true).

Common situations: CI pipelines or scripts calling destroy non-interactively against the default env; shell scripts piped through ssh where stdin is not a terminal; forgetting --force after adding --env.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/6b211072a7e5e722. Report an issue: GitHub.